EDIT : Summary of answers
In the following, B is a subclass of A.
It's a matter of terminology; ctors and dtors are not inherited, in the sense that the ctor/dtor of B will not be borrowed from A's interface. A class has at least one constructor, and has exactly one destructor.
- Constructors:
- B does not inherit constructors from A;
- Unless B's ctor explicitely calls one of A's ctor, the default ctor from A will be called automatically before B's ctor body (the idea being that A needs to be initialized before B gets created).
- Destructors:
- B does not inherit A's dtor;
- After it exits, B's destructor will automatically call A's destructor.
Acknowledgements: I would like to thank especially Oli Charlesworth and Kos for their answers, I set Kos' answer as the solution because it was the one I understood best.
ORIGINAL POST
When you search for "C++ destructor inheritance site:stackoverflow.com" on Google, you currently find the following posts:
- Constructor and Destructor Inheritance: two users with 30k+ reputation say that it is inherited, and that it's not
- Are virtual destructors inherited?: here nothing is mentioned that would point to destructors not being inherited
- Destructors and inheritance in C++?: The comments seem to indicate the destructors are inherited
Q1: What I also know from practice, is that you cannot initialize a derived object with the same prototype than it's parent constructor without explicitely defining a constructor for the derived class, is that correct?
Even though it's rather clear from the posts that destructors seem to be inherited, I'm still puzzled by the fact that a user with 32k reputation would say its not. I wrote a little example that should clarify everyone's mind:
#include <cstdio>
/******************************/
// Base class
struct A
{
A() { printf( "\tInstance counter = %d (ctor)\n", ++instance_counter ); }
~A() { printf( "\tInstance counter = %d (dtor)\n", --instance_counter ); }
static int instance_counter;
};
// Inherited class with default ctor/dtor
class B : public A {};
// Inherited class with defined ctor/dtor
struct C : public A
{
C() { printf("\tC says hi!\n"); }
~C() { printf("\tC says bye!\n"); }
};
/******************************/
// Initialize counter
int A::instance_counter = 0;
/******************************/
// A few tests
int main()
{
printf("Create A\n"); A a;
printf("Delete A\n"); a.~A();
printf("Create B\n"); B b;
printf("Delete B\n"); b.~B();
printf("Create new B stored as A*\n"); A *a_ptr = new B();
printf("Delete previous pointer\n"); delete a_ptr;
printf("Create C\n"); C c;
printf("Delete C\n"); c.~C();
}
and here is the output (compiled with g++ 4.4.3):
Create A
Instance counter = 1 (ctor)
Delete A
Instance counter = 0 (dtor)
Create B
Instance counter = 1 (ctor)
Delete B
Instance counter = 0 (dtor)
Create new B stored as A*
Instance counter = 1 (ctor)
Delete previous pointer
Instance counter = 0 (dtor)
Create C
Instance counter = 1 (ctor)
C says hi!
Delete C
C says bye!
Instance counter = 0 (dtor) // We exit main() now
C says bye!
Instance counter = -1 (dtor)
Instance counter = -2 (dtor)
Instance counter = -3 (dtor)
Q2: Can anybody who thinks it's not inherited please explain that?
Q3: So what happens when you call the constructor of a subclass with inputs? Is the "empty constructor" of the superclass called as well?
a.~A();
directly puzzles me, having Instance counter going to -3 too. Ain't your code would be clearer like this{printf("Create A\n"); A a; printf("Delete A\n");} {printf("Create B\n"); B b; printf("Delete B\n");} ...
? I.e. going out of scope calls automatically the dtor so you will not have to call destructor explicitly and Instance counter will end at 0 . – Schematize