C++ Constructor/Destructor Inheritance

C++ Constructor/Destructor inheritance

Terminology, terminology...

OK, what do we mean by "Foo is inherited"? We mean that if objects of class A have Foo in its interface, then objects of class B which is a subclass of A also have Foo in its interface.

  • Constructors aren't a part of objects' interface. They belong directly to classes. Classes A and B may provide completely different sets of constructors. No "being inherited" here.

    (Implementation detail: each B's constructors calls some A's constructor.)

  • Destructors indeed are a part of each object's interface, since the object's user is responsible for calling them (i.e. directly with delete or indirectly by letting an object out of scope). Each object has exactly one destructor: its own destructor, which might optionally be a virtual one. It is always its own, and it's not inherited.

    (Implementation detail: B's destructor calls A's destructor.)

So: there's a connection between base and derived constructors and destructors, but it's not like "they're inherited".

I hope this answers what you have in mind.

Constructor and Destructor Inheritance

Your understanding is correct. For example, if you have

class Base
{
Base(int i) {}
};

class Derived: public Base {};

Derived d(3);

This will not compile because the Base constructor is not inherited.
Note that default and copy constructor are created by the compiler if possible, and call the corresponding constructor of base classes, therefore for those constructors it looks as if those were inherited.

Destructors and inheritance in C++?

This can be solved at TObject's level. Its destructor has to be virtual:

#include <Classes.hpp>
class TObject
{
__fastcall TObject();
virtual __fastcall ~TObject();
};

This way you can either do:

TObject * pobj = new TMyObject();
delete pobj;

or

TMyObject * pobj = new TMyObject();
delete pobj;

Both destructors will be called (~TMyObject() first and then ~TObject()) and you will have no leak.

What is the order in which the destructors and the constructors are called in C++

The order is:

  1. Base constructor
  2. Derived constructor
  3. Derived destructor
  4. Base destructor

Example:

class B
{
public:
B()
{
cout<<"Construct B"<<endl;
}

virtual ~B()
{
cout<<"Destruct B"<<endl;
}
};

class D : public B
{
public:
D()
{
cout<<"Construct D"<<endl;
}

virtual ~D()
{
cout<<"Destruct D"<<endl;
}
};

int main(int argc, char **argv)
{
D d;
return 0;
}

Output of example:

Construct B

Construct D

Destruct D

Destruct B

Multiple levels of inheritance works like a stack:

If you consider pushing an item onto the stack as construction, and taking it off as destruction, then you can look at multiple levels of inheritance like a stack.

This works for any number of levels.

Example D2 derives from D derives from B.

Push B on the stack, push D on the stack, push D2 on the stack. So the construction order is B, D, D2. Then to find out destruction order start popping. D2, D, B

More complicated examples:

For more complicated examples, please see the link provided by @JaredPar

Using Destructor in inheritance

The first "A Disturctor" is for object "A hamza(1)".
The second "A Disturctor" is for object "B Ramza(4)"

Since B inherits from A, when object of class B is destroyed, destructor of both class B and class A are called.

Call of the destructors in multilevel inheritance (c++)

Inheritance is a red herring here. It's not relevant.

y and z have automatic storage duration and are required, in this case, to stay in scope until the closing brace of the function.

And z will be destructed before y. (Automatic variables go out of scope in the reverse order in which they were created, all other things being equal.)

In C++ Inheritance, Derived class destructor not called when pointer object to base class is pointed to derived class

Your code has undefined behavior. The base class's destructor must be virtual for the following to have defined behavior.

Base* b = new Derived;    
delete b;

From the C++ standard:

5.3.5 Delete

3 In the first alternative (delete object), if the static type of the
operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined.

So in your case, the static type is Base, and the dynamic type is Derived. So the Base's destructor should be:

virtual ~Base() {cout << "Base Destructor\n"; }

C++ inheritance and constructors, destructors

$ cat Parent.h 
#ifndef GUARD_PARENT_H_
#define GUARD_PARENT_H_

class Parent{
public:
Parent(){}
~Parent(){}
virtual void func1() = 0;
};

#endif /* GUARD_PARENT_H_ */
$ cat Child.h
#ifndef GUARD_CHILD_H_
#define GUARD_CHILD_H_

#include "Parent.h"

class Child : public Parent{
int x, y;
public:
Child();
virtual void func1();
};

#endif /* GUARD_CHILD_H_ */
$ cat Child.cpp
#include "Child.h"

Child::Child() : Parent() {
}

void Child::func1(){
}
$ cat try.cc
#include "Child.h"

int main() {
Child c;
}
$ g++ try.cc Child.cpp
$ ./a.out
$


Related Topics



Leave a reply



Submit