Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does enable_shared_from_this have a non-virtual destructor?

Tags:

I have a pet project with which I experiment with new features of C++11. While I have experience with C, I'm fairly new to C++. To train myself into best practices, (besides reading a lot), I have enabled some strict compiler parameters (using GCC 4.4.1):

-std=c++0x -Werror -Wall -Winline -Weffc++ -pedantic-errors

This has worked fine for me. Until now, I have been able to resolve all obstacles. However, I have a need for enable_shared_from_this, and this is causing me problems. I get the following warning (error, in my case) when compiling my code (probably triggered by -Weffc++):

base class ‘class std::enable_shared_from_this<Package>’ has a non-virtual destructor

So basically, I'm a bit bugged by this implementation of enable_shared_from_this, because:

  • A destructor of a class that is intended for subclassing should always be virtual, IMHO.
  • The destructor is empty, why have it at all?
  • I can't imagine anyone would want to delete their instance by reference to enable_shared_from_this.

But I'm looking for ways to deal with this, so my question is really, is there a proper way to deal with this? And: am I correct in thinking that this destructor is bogus, or is there a real purpose to it?

like image 843
Stéphan Kochen Avatar asked Apr 03 '10 16:04

Stéphan Kochen


People also ask

Is there a non-virtual destructor?

A C++ class containing virtual member functions has a non-virtual destructor. Since this class has virtual member functions, it will be used as a base class. The use of non-virtual destructors in base classes is dangerous because it can cause objects to be torn down incorrectly.

Which has non-virtual destructor might cause undefined behavior?

Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results in undefined behavior. To correct this situation, the base class should be defined with a virtual destructor.

What is shared_ from_ this?

std::enable_shared_from_thisThe class provides functionality that allows objects of derived classes to create instances of shared_ptr pointing to themselves and sharing ownership with existing shared_ptr objects.


2 Answers

A destructor of a class that is intended for subclassing should always be virtual, IMHO.

A virtual destructor in a base class is only needed if an instance of the derived class is going to be deleted via a pointer to the base class.

Having any virtual function in a class, including a destructor, requires overhead. Boost (and the TR1 and C++11 Standard Library) doesn't want to force you to have that overhead just because you need to be able to obtain a shared_ptr from the this pointer.

The destructor is empty, why have it at all?

If you don't have a user-defined constructor, the compiler provides one for you, so it doesn't really matter.

I can't imagine anyone would want to delete their instance by reference to enable_shared_from_this.

Exactly.

As for the compiler warning, I would ignore the warning or suppress it (with a comment in the code explaining why you are doing so). Occasionally, especially at "pedantic" warning levels, compiler warnings are unhelpful, and I'd say this is one of those cases.

like image 200
James McNellis Avatar answered Oct 21 '22 03:10

James McNellis


I agree with Jame's description, but would add

A virtual destructor is only required if you want to destroy an instance of that class virtually. This is not always the case, however if a base class is not intended to be destroyed virtually it should protect against it

So I would change

A destructor of a class that is intended for subclassing should always be virtual, IMHO.

this to be:

A destructor of a class that is intended for subclassing should always be virtual or protected.

like image 30
iain Avatar answered Oct 21 '22 02:10

iain