Reputation: 2914
I need to declare finalizing method finalize()
for all descendants of the base class Base
, that should be called during destruction, and my intent was to call pure virtual void Base::finalize() = 0
from the ~Base()
, but c++ forbids such a thing. So my question is
How can we oblige descendants to do some finalizing work in right and preliminary defined way?
That code cannot be compiled:
#include <QDebug>
class Base {
public:
Base(){}
virtual ~Base(){
qDebug("deleting b");
finalize();
}
virtual void finalize() = 0;
};
class A : public Base
{
public:
A(){}
~A(){}
void finalize(){qDebug("called finalize in a");}
};
int main(int argc, char *argv[])
{
Base *b = new A;
delete b;
}
If I make Base::finalize()
not pure virtual, it is called from ~Base()
without dispatching to child since it have been already destructed.
I can call finalize() from child's destructor but question is how to force to do that. In other words my question is: is it possible to oblige people who will write descendants of the Base class to use finalizing method, well, in another way than commenting it in a documentation? :)
Upvotes: 7
Views: 5455
Reputation: 6972
Destructors are the right place to release acquired resources, but each class is responsible to release its own resources. Resources acquired by class A
should not (and just can not) be released by class Base
.
Defining virtual destructors allows class A
's destructor to be called when deleting a pointer to class Base
pointing to a class A
object
Base* p = new A;
delete p; // Both A and Base destructors are sequencially called!
So to achieve proper resource release you just have to release each class' resources in its own destructor.
Upvotes: 9
Reputation: 35
Why not use the desctructor of Base? That what are destructors are made for.
Make search RAII and discover one of the finest things in c++.
Most people used to use other languages have to discover this. Resource management in c++ is completely different than in most other computer languages
Upvotes: 0
Reputation: 96241
Make the base class destructor pure virtual with a body, which should do exactly what you want.
Upvotes: 2
Reputation: 258588
That's what a virtual destructor is for:
class A
{
public:
virtual ~A() {}
};
class B : public A
{
public:
virtual ~B() {}
};
When an object of type B
is destroyed, regardless of whether from a pointer to a B
or a pointer to an A
, both destructors will be called. First, B::~B()
and then A::~A()
.
Upvotes: 3