为什么enable_shared_from_this有一个非虚拟析构函数?

时间:2010-04-03 16:25:48

标签: c++ gcc boost c++11 shared-ptr

我有一个宠物项目,我用它来试验C ++ 11的新功能。虽然我有C的经验,但我对C ++还不熟悉。为了训练自己进入最佳实践,(除了阅读很多),我已经启用了一些严格的编译器参数(使用GCC 4.4.1):

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

这对我来说很好。到现在为止,我已经能够解决所有障碍。但是,我需要enable_shared_from_this,这会给我带来麻烦。编译我的代码时可能会收到以下警告(在我的情况下是错误的)(可能由-Weffc++触发):

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

所以基本上,我对enable_shared_from_this的这种实现有点怀疑,因为:

  • 用于继承的类的析构函数应始终是虚拟的,恕我直言。
  • 析构函数是空的,为什么要这样呢?
  • 我无法想象有人会想通过引用enable_shared_from_this删除他们的实例。

但我正在寻找解决这个问题的方法,所以我的问题是,是否有正确的方法来解决这个问题?而且:我认为这个析构函数是虚假的,或者它是否有真正的目的,我是否正确?

3 个答案:

答案 0 :(得分:24)

  

用于子类化的类的析构函数应始终是虚拟的,恕我直言。

只有在通过指向基类的指针删除派生类的实例时,才需要基类中的虚析构函数。

在类中包含任何虚函数(包括析构函数)都需要开销。 Boost(以及TR1和C ++ 11标准库)不希望因为你需要能够从shared_ptr指针获得this而强迫你获得这种开销。

  

析构函数是空的,为什么要这样呢?

如果你没有用户定义的构造函数,编译器会为你提供一个,所以它并不重要。

  

我无法想象有人会想通过引用enable_shared_from_this删除他们的实例。

完全。

至于编译器警告,我会忽略警告或禁止它(在代码中用注释解释你为什么这样做)。偶尔,特别是在“迂腐”警告级别,编译器警告是无益的,我会说这是其中一种情况。

答案 1 :(得分:9)

我同意Jame的描述,但会添加

只有在想要虚拟地销毁该类的实例时才需要虚拟析构函数。情况并非总是如此,但是如果基本类不打算被破坏,那么它应该防止它

所以我会改变

  

类的析构函数   用于子类化的应始终   是虚拟的,恕我直言。

这是:

  

类的析构函数   用于子类化的应该   始终虚拟受保护

答案 2 :(得分:4)

  

有没有正确的方法来解决这个问题?

不要一直使用-Weffc++。有时打开它来检查你的代码是有用的,但不是真的永久使用它。它给出了误报,而且这些天并没有得到真正的维护。偶尔使用它,但请注意,您可能不得不忽略某些警告。理想情况下,只需记住迈耶斯书中的所有建议,然后无论如何你都不需要它; - )

  

我认为这个析构函数是虚假的,或者它有真正的目的吗?

不,这不是假的,而且有真正的目的。 如果未定义,则将隐含声明为public,以防止它明确声明为protected