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++ destructor not working as intended
You should make the destructor of Aa
virtual:
class Aa {
public:
virtual ~Aa();
};
This is a basic concept of c++. You can read on it here (and in many other places).
Virtual Destructor Not called in Base as well as Derived Class
You must decide who owns the SalaryTable
that each Lecturer
receives a pointer to at construction.
There are two similar options.
(1) the table is explicitly owned by another class/code (not shown in your question), then the Lecturer
should keep an observing pointer (or reference) to the table (a const SalaryTable*const
or SalaryTable&
or similar) which is never used to delete
and the code layout must guarantee that a SalaryTable
is not destroyed before any Lecturer
observing it.
(2) you can ensure this latter using std::shared_ptr
, but this comes at some price and also means that there is no owner to the SalaryTable
, but that all those parts of code which keep a shared_ptr
to it jointly keep ownership.
To me (1) appears the more logical: a SalaryTable
is a fundamental object that exists indepedent of any Lecturer
and should be created before any Lecturer
and destroyed after any Lecturer
. I also suggest to avoid shared_ptr
if you don't have some experience with it.
Destructor when derived class contains a pointer to base class object
However, in one of the classes I have a pointer to a base class object.
Now, should the destructor of the derived class be written this way
Since pointerToAnotherDerivedClassObject
points at another object in memory, then yes, your DerivedClass
destructor needs to explicitly delete
that object (or wrap the raw pointer inside a smart pointer - std::auto_ptr
, std::unique_ptr
, or std::shared_ptr
- and let it delete
the object for you) ONLY IF DerivedClass
is meant to own that other object. Otherwise, do not delete
it if you do not own it.
Base class has no destructor, but derived class does. Do I need to look for any pitfalls that DON'T relate to the heap?
Your base class has an implicit destructor. All will be fine.
A virtual base class destructor is used to allow a derived constructor to run when destructing via a pointer or reference to the base class. So in your case, this would be unsafe:
void destruct(Base &b) { b.~Base(); }
Derived d; destruct(d);
But this will be perfectly safe:
void destruct(Derived &d) { d.~Derived(); }
Derived d; destruct(d);
Destructor when derived class contains a pointer to base class object
However, in one of the classes I have a pointer to a base class object.
Now, should the destructor of the derived class be written this way
Since pointerToAnotherDerivedClassObject
points at another object in memory, then yes, your DerivedClass
destructor needs to explicitly delete
that object (or wrap the raw pointer inside a smart pointer - std::auto_ptr
, std::unique_ptr
, or std::shared_ptr
- and let it delete
the object for you) ONLY IF DerivedClass
is meant to own that other object. Otherwise, do not delete
it if you do not own it.
Why base class destructor (virtual) is called when a derived class object is deleted?
The Standard says
After executing the body of the destructor and destroying any automatic objects allocated within the body,
a destructor for class X calls the destructors for X’s direct non-variant members,the destructors for X’s direct
base classes and, if X is the type of the most derived class (12.6.2), its destructor calls the destructors for
X’s virtual base classes. All destructors are called as if they were referenced with a qualified name, that is,
ignoring any possible virtual overriding destructors in more derived classes. Bases and members are destroyed
in the reverse order of the completion of their constructor (see 12.6.2). A return statement (6.6.3) in a
destructor might not directly return to the caller; before transferring control to the caller, the destructors
for the members and bases are called. Destructors for elements of an array are called in reverse order of
their construction (see 12.6).
Also as per RAII resources need to be tied to the lifespan of suitable objects and the destructors of respective classes must be called upon to release the resources.
For example the following code leaks memory.
struct Base
{
int *p;
Base():p(new int){}
~Base(){ delete p; } //has to be virtual
};
struct Derived :Base
{
int *d;
Derived():Base(),d(new int){}
~Derived(){delete d;}
};
int main()
{
Base *base=new Derived();
//do something
delete base; //Oops!! ~Base() gets called(=>Memory Leak).
}
I wonder why there is an error calling the destructor in the inheritance
Your code invokes undefined behavior.
Excerpt from the "Effective C++" book by Scott Meyers explains why:
When derived class object is deleted through a pointer to a base class
with a non-virtual destructor, results are undefined.
Your base class A
should have a virtual destructor:
virtual ~A() { std::cout << "A Destroyer" << '\n'; }
If classes are meant to be used in polymorphic ways then the base class should have the virtual destructor.
Related Topics
How to Legally Reinterpret_Cast Between Layout-Compatible Standard-Layout Types
Alpha Rendering Difference Between Opengl and Webgl
What am I Allowed to Do with a Static, Constexpr, In-Class Initialized Data Member
Convert Inline Assembly Code to C++
Why Is a Default Constructor Required When Storing in a Map
Is It More Efficient to Copy a Vector by Reserving and Copying, or by Creating and Swapping
How to Set Up Unit Testing for Visual Studio C++
Memory Alignment:How to Use Alignof/Alignas
C++ Issue with Cin and Ctrl + Z
How to Send Sms Using at Commands
If Statement Not Working Right
Implementation of Permutation, Combinations and Powerset in C++
Why Use #Ifndef Class_H and #Define Class_H in .H File But Not in .Cpp
Is There a C++ Gdb Gui for Linux