C++ Qt base class virtual destructor - c++

Do we need a virtual destructor for a classes which are gonna be used in Qt-way: set QObject-parent which will call in QObject's destructor deleteLater() or something like that for any object for which it was set as parent?
For example:
class MyWidget : public QWidget {
public:
MyWidget() {
w = new QWidget(this);
// "w" will be deleted automatically by parent MyWidget::QWidget::QObject's destructor afaik
}
private:
QWidget *w;
}
Do we need a virtual destructor for MyWidget class if it is gonna be inherited? I see no reason for this because it does not delete anything and each property of the class which is derived from QObject will be deleted from MyWidget::QWidget::QObject's destructor.

It doesn't matter if you add it or not as QObject inherited by QWidget has a virtual destructor, and this is propagated through the whole hierarchy.

You don't need to explicitly write an (empty) virtual destructor because QWidget already marks its distructor as virtual, so automatically all destructors of the class hierarchy are virtual.
But in general, if you write a class that is going to be inherited (and doesn't already have a base class with a virtual destructor), always specify a virtual destructor, otherwise things will blow up badly if anyone tries to destroy an object of your class hierarchy through a pointer of the base class type.

Related

Call overrided methods of descendants from virtual destructor of base class

Let's say we have codes like follow:
class Base{
public:
virtual ~Base(){PutStat();};
virtual void PutStat(){/* maybe do nothing */};
};
class Desend : public Base{
public:
void PutStat() override{/* do something */};
};
Method PutStat will print some statistic. I hope every instance of Descendants inherited from Base could automatically print a statistic message while destructing.
It seems like a common feature here to output stat-message, so I think it's more reasonable to call PutStat just once in Base than call PutStat in each descendants separately.
Unfortunately, as destructor in Base is virtual, thus un-overrided PutSat will be called.
So how to call the overrided version of PutStat in Base destructor.
Unfortunately, as destructor in Base is virtual, thus un-overrided PutSat will be called.
Correct, but not for that reason. The destructor being virtual has nothing to do with it. The base class's methods will be called because the object has been partially destroyed back to the base class, which includes causing its VFT be that of a base class instance.
How to call the overridden version
You can't. It's gone. The object has gone. It wouldn't make sense, so C++ doesn't allow it.

When and why should destructor in base class NOT be defined as virtual?

This example below illustrates how to prevent derived class from being copied. It's based on a base class where both the copy constructor and copy assignment operator are declared private.
class Uncopyable
{
protected:
// allow construction and destruction of derived objects...
Uncopyable() {}
~Uncopyable() {}
private:
// but prevent copying...
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
We can use this class, combined with private inheritance, to make classes uncopyable:
class derived: private Uncopyable
{...};
Notice that the destructor in class Uncopyable is not declared as virtual.
Previously, I learned that
Destructors in base classes should be virtual.
Destructors in non-base classes should not be made virtual.
In this example, the destructor for Uncopyable is not virtual, but it is being inherited from. This seems to go against the wisdom I've learned previously.
When and why should destructor in base class NOT be defined as virtual?
A base class destructor only needs to be virtual if you might try deallocating an object of a derived type through a pointer of the base type. Consequently, if you only inherit from the base class privately instead of publicly, as would be the case in Uncopyable, then you don't need to worry about putting in a virtual destructor, because when using private inheritance you can't get a pointer to the derived object and store it in a pointer to the base type.
Another example might be if you were to use a mixin class like this one that makes a class track the number of object allocations, where the mixin is inherited from to acquire behavior but not to be treated polymorphically:
template <typename T> class Counter {
public:
Counter() { ++numInstances; }
Counter(const Counter&) { ++numInstances );
~Counter() { --numInstances; }
static unsigned getNumInstances() { return numInstances; }
private:
static unsigned numInstances;
}
template <typename T> unsigned Counter<T>::numInstances = 0;
More generally, when using static polymorphism, you don't need virtual destructors because you never treat the classes polymorphically using pointers to the base type. You only use a pointer to the derived type.
There are probably a few other cases I didn't cover here, but these two (private inheritance, mixin classes, and static polymorphism) cover much of the space where virtual destructors aren't required.
When you design the base not as interface, but as implementation detail (note the private inheritance from Uncopyable).
You technically don't have to make your decostructor virtual if you know nobody will delete it as a Uncopyable*, but will always delete it as a subclass of the same.
Yes this is essentially, what #templatetypedef said, but I'm going to explain it in a maybe easier way.
So: if people might do something like this:
void aFunction(Uncopyable* obj) {
delete obj;
}
Then you should declare your destructor virtual (to make sure potential subclasses get their destructor called.
However, if you know people will be deleting Subclasses like so:
class Widget : public Uncopyable
{
....
};
void aFunction(Widget* obj) {
delete obj;
}
Then you don't have to make your destructor virtual (as the subclasses destructor will be called).
At least, that's my understanding.
When you need your objects to be plain old data, with no vtable. I'd comment the heck out of it if I ever needed it, as 99% of the time leaving off the 'virtual' in base class destructors is simply a mistake that someone will want to correct.
The general rule is to make your destructor public and virtual, or protected and non-virtual. In the first case, your object use destroyable polymorphically and teh virtual destructor will do the right thing. In the second case it will only be destroyed as the actual child class and still do the right thing.

Destructors and inheritance in C++?

I use Borland C++ Builder.
And i had o problem
#include <Classes.hpp>
class TMyObject : public TObject
{
__fastcall TMyObject();
__fastcall ~TMyObject();//I would like to inherite my destructor from TObject
};
__fastcall TMyObject::TMyObject() : TObject()//it will inherited my constructor from TObject
{
}
And for that new destructor that will inherite ~TObject?
__fastcall TMyObject::~TMyObject?????????????
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.
Destructor of the Base class will be automatically called by the compiler, when your objet life time ends. you do not need to call it explicitly.
TMyObject::TMyObject() : TObject()
Does not inherit the constructor.
It is called as Member initializer list and it initializes the Base class object with a particular value.
When you create the object.
TMyObject obj;
The constructors will be called in order:
constructor of TObject
constructor of TMyObject
When the object life time ends the destructors will be called in the order:
destructor of TMyObject
destructr of TObject
The compiler will do so for you, do not need to call it explicitly.
If you destroy a TMyObject through a reference of type TMyObject you don't have to do anything. In case you have a pointer/reference of type TObject to a TMyObject things will go wrong. Only the TObject destructor will be called, not the TMyObject one:
TObject* p = new TMyObject;
delete p; // Only the TObject::~TObject is called, not TMyObject::~TMyObject.
To have the decision on what destructor to call deferred to runtime, you need to specify the destructor as virtual in TObject. Whenever you have a class that is intended to be derived from, the destructor should be virtual. Otherwise there is always a risk for resource leaks when the derived class destructor isn't called properly.
What's causing the confusion to you is that you can specifically mention "which" constructor of the base class you want to use as in the following example. But you can't/ don't need to specify the destructor.
TMyObject::TMyObject() : TObject()
You could use a different constructor, say TObject (int i) by writing
TMyObject::TMyObject() : TObject (3)
An object can be destructed in only one way but it can be constructed in several ways (by having different constructors).
So, in short, you don't need to mention the name of the base class destructor in the derived class destructor. As soon as you destroy the derived object (say, by doing delete derivedObj), it will first call the derived class destructor and then base class destructor by itself.

need to call the base destructor method from a derived class in c++? [duplicate]

This question already has answers here:
Do I need to explicitly call the base virtual destructor?
(7 answers)
Closed 7 years ago.
Please consider the following:
class base{
base();
~base();
}:
class derived : public base{
};
Does a base class destructor get automatically invoked when a derived object is destructed when the derived class has no destructor defined?
Otherwise, if I DO have a destructor in the derived class too, do I have to call the base class destructor explicitly?
class base{
base();
~base();
}:
class derived : public base{
derived();
~derived{
base::~base(); //do I need this?
}
};
The base class destructor is automatically invoked in this case; you do not need to call it.
However, note that when destroying an object through delete on a base class pointer and the destructor is not virtual, the result is going to be undefined behavior (although you might not get a crash).
Always declare the destructor as virtual in any class which is meant to be derived from. If the base class does not need to have a destructor, include a virtual one anyway with an empty body.
There is an exception to the above rule for an edge case: if your derived classes do not need to support polymorphic destruction, then the destructor does not need to be virtual. In this case it would be correct to make it protected instead; more details here, but be advised that this rarely occurs in practice.
Does a base class destructor is automatically invoked when a derived object is destructed and the derived class has no destructor defined?
Yes, the Base class destructor is automatically invoked after the Derived class Destructor, irrespective of Derived class destructor being explicitly defined or not.
Otherwise, if I have a destructor in the derived class too, do I need to call explicitly base class destructor too?
No, You don't need to.
There will not be any scenario in C++, where one has to explicitly invoke a destructor except while using placement new.
No, base destructors are invoked automatically in this case, in much the same way that base constructors are can be invoked automatically.
Note, though, that if you are using polymorphism and destroying through a base pointer, you should make sure that the destructor is virtual otherwise this will break.
You should never invoke a base class destructor from a derived class destructor.
The reason is base class destructor will be then called automatically for the second time and writing destructors in such way that this doesn't cause problem is problematic - see this question.

Virtual destructor for boost:noncopyable classes?

I have a question about the following code:
class MyClass : private boost::noncopyable
{
public:
MyClass() {}
virtual ~MyClass() {}
}
class OtherClass : private boost::noncopyable
{
private:
MyClass* m_pMyClass;
}
My thoughts are that MyClass cannot be copied using construction or assignment. Using a virtual destructor is needed if I want to support deriving classes from MyClass, which I do not want to support. I do not intend to create pointers to this class and pass them around.
I do not want a Singleton and I cannot see a downside to removing the virtual destructor.
Do I introduce a potential problem if remove the virtual destructor for a noncopyable class? Are there a better practices to handle a class that does not need to be a Singleton, but I only want one instance in another class and not support inheritance?
No, the entire point of a virtual destructor is so derived classes can properly destruct polymorphically. If this will never be a base class, you don't need it to be virtual.
The general rule is if your class has virtual functions it needs a virtual destructor. If it doesn't, but is still derived from a base class, the base class (and hence your class) may or may not need a virtual destructor depending.
Deriving your class from boost::noncopyable doesn't really count as being derived from a base class. boost::noncopyable is more like a convenient annotation backed up with a couple of declarations that will cause the compiler to enforce the annotation. It's not really a base class in any conventional sense. Nobody is ever going to try to pass around a pointer to your class as a pointer or reference to boost::noncopyable. And even if they did your virtual destructor wouldn't help because the boost::noncopyable's destructor isn't.
And lastly, as was pointed out in a comment, you are even privately inheriting from boost::noncopyable so it's not even really inheritance at all as far as anybody outside the class is concerned.
So really, no need to make it a virtual destructor.
I'm really not a fan of the boost::noncopyable class as a whole. Why not just declare your class's copy constructor and assignment operator private and not define them. That will accomplish the same thing, and you can ditch the virtual destructor.
Boost only supplies a virtual destructor so that people can pass around boost::noncopyable objects polymorphic and still have them behave well. Technically speaking if you are not going to use the class polymorphically (you can even still inherit from it), you really don't need a virtual destructor.
Virtual destructor in base class is used to avoid partial destruction problem like :
Base *pBase = new Derived();
delete pBase;
//if destructor is not made virtual then derived class destructor will never called.
When you inherit a class privately , compiler won't perform implicit casting from derived to base class and if you are sure that derived object is never destructed using base class pointer then you don't need virtual destructor in base class.
Base *pBase = new Derived(); // will flash error
boost::noncopyable is meant to say that you don't want copies of the object made. You're aware that this is different from deriving from the object.
It is perfectly fine to get rid of the virtual destructor if you won't ever derive from the object. If you want to enforce the "don't derive from this object" policy, there is a way. Unfortunately, there is no boost::nonderivable to pretty this up for you.
As mentioned in the link, C++11 allows you to declare the class final:
class MyClass : final private boost::noncopyable { ... };