jj@idris.id.dk (Jesper Joergensen [ris]) (02/14/90)
ENVIRONMENT =========== Compiler: G++ version 1.36.4 (configured for 'vax') Back-end: GCC version 1.36.93 (configured for 'vax') System: Ultrix version 2.2-1 Worksystem v1.1 System #2 Machine: DEC VAXstation 2000 SUMMARY ======= Given the following classes: Base1: with a virtual destructor Base2: with a normal destructor Derived1: derived public from Base1 and private from Base2, without an explicitly defined destructor Derived2: derived public from Base1 and private from Base2, with an empty (dummy) destructor When an object of class Derived1 is delete'ed through a pointer to Base1 the virtual destruction FAILS to invoke the destructor for Base2. However, when an object of class Derived2 is delete'ed through a pointer to Base1 the virtual destruction WILL invoke the destructor for Base2. EXAMPLE PROGRAM =============== ****** START ****** #include <stream.h> class Base1 { // Base with virtual destructor int member1 ; public: virtual ~Base1() { cout << "~Base1() executed\n" ; } Base1(int x) { cout << "Base1(int x) executed\n" ; member1 = x ; } } ; class Base2 { // Base with normal destructor int member2 ; public: ~Base2() { cout << "~Base2() executed\n" ; } Base2(int x) { cout << "Base2(int x) executed\n" ; member2 = x ; } } ; class Derived1 : public Base1, Base2 { // Derived without explicit destructor public: Derived1(int x) : Base1(x), Base2(x) { cout << "Derived1(int x) executed\n" ; } } ; class Derived2 : public Base1, Base2 { // Derived with empty destructor public: ~Derived2() { } Derived2(int x) : Base1(x), Base2(x) { cout << "Derived2(int x) executed\n" ; } } ; int main(const int argc, const char *argv) { Base1 *_bptr ; _bptr = new Derived1(12) ; // Why isn't ~Base2() called here .... delete _bptr ; _bptr = new Derived2(12) ; // When it is called here ???? delete _bptr ; return 0 ; } ******* END ******* EXAMPLE OUTPUT ============== ****** START ****** Base1(int x) executed Base2(int x) executed Derived1(int x) executed ~Base1() executed Base1(int x) executed Base2(int x) executed Derived2(int x) executed ~Base2() executed ~Base1() executed ******* END ******* Am I missing something ?? I can't find anything demanding the call of ~Base2() in the first case, but it seems obvious that it should. The destruction of ALL base classes in other situation have always been independent of whether the derived class has a destructor itself. Please inform me if I'm wrong, so that I know my way in the future. Jesper Jorgensen jj@idris.id.dk Research associate Department of Computer Science Technical University of Denmark DK-2800 Lyngby DENMARK