views:

58

answers:

2

hey there, why is the base destructor called twice at the end of this program?

#include <iostream>
using namespace std;

class B{
public:
  B(){
    cout << "BC" << endl; x = 0;
  }
  virtual ~B(){
    cout << "BD" << endl;
  }
  void f(){
    cout << "BF" << endl;
  }
  virtual void g(){
    cout << "BG" << endl;
  }
private:
  int x;
};

class D: public B{
public:
  D(){
    cout << "dc" << endl; y = 0;
  }
  virtual ~D(){
    cout << "dd" << endl;
  }
  void f(){
    cout << "df" << endl;
  }
  virtual void g(){
    cout << "dg" << endl;
  }
private:
  int y;
};

int main(){
  B b, * bp = &b;
  D d, * dp = &d;
  bp->f();
  bp->g();
  bp = dp;
  bp->f();
  bp->g();
}
+2  A: 

Once it is called for b and once for d

Note when destructor of D called it is automatically calls the destructor of B it is different from ordinary virtual functions. where you need explicitly call base class function to use it.

Artyom
but virtual ~D() was called giving me dd. Why does it go back and do it again? (meaning base class)
sil3nt
@sli3nt - read my edit
Artyom
so virtual ~D() gives dd and BD, and then virtual ~B() gives another BD correct?. sorry for being annoying lol:)
sil3nt
@sil3nt: If I'm understanding your question / confusion correctly, does this help: the base destructor (BD) is called twice, but not twice on the same object. It is called once when B b is destroyed, and *once* when D d is destroyed. As others have mentioned, when D is destroyed, the destructor of the base class B is also automatically called. So you're seeing the B destructor called one time each for 2 different objects, hence 2 times -- not twice for one object.
Dan
thanks Dan, go it now. - cheers
sil3nt
+2  A: 

Destructors are called in order, as if they were unwinding the effects of the corresponding constructors. So, first the destructors of the derived objects, then the destructors of the base objects. And making the destructors virtual doesn't have any impact on calling / not calling the base class destructor.

Also to mention, your example could be simplified this way (this code also results in calling the base destructor twice and the derived destructor once):

struct A {
   ~A() {
      // ...
   }
};

struct B: A {
   ~B() {
      // ...
   }
};

int main() {
   A a;
   B b;
}
Kotti