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 o开发者_运维知识库bstacles. 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?
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.
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.
is there a proper way to deal with this?
Don't use -Weffc++
all the time. It's useful to turn it on sometimes to check your code, but not really to use it permanently. It gives false positives and is not really maintained these days. Use it now and then, but be aware you might have to ignore some warnings. Ideally, just memorise all the advice in the Meyers books and then you don't need it anyway ;-)
am I correct in thinking that this destructor is bogus, or is there a real purpose to it?
No, it's not bogus and has a real purpose. If it wasn't defined it would be implicity-declared as public
, to prevent that it is explicitly declared as protected
.
精彩评论