我有一个宠物项目,我用它来试验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
删除他们的实例。但我正在寻找解决这个问题的方法,所以我的问题是,是否有正确的方法来解决这个问题?而且:我认为这个析构函数是虚假的,或者它是否有真正的目的,我是否正确?
答案 0 :(得分:24)
用于子类化的类的析构函数应始终是虚拟的,恕我直言。
只有在通过指向基类的指针删除派生类的实例时,才需要基类中的虚析构函数。
在类中包含任何虚函数(包括析构函数)都需要开销。 Boost(以及TR1和C ++ 11标准库)不希望因为你需要能够从shared_ptr
指针获得this
而强迫你获得这种开销。
析构函数是空的,为什么要这样呢?
如果你没有用户定义的构造函数,编译器会为你提供一个,所以它并不重要。
我无法想象有人会想通过引用
enable_shared_from_this
删除他们的实例。
完全。
至于编译器警告,我会忽略警告或禁止它(在代码中用注释解释你为什么这样做)。偶尔,特别是在“迂腐”警告级别,编译器警告是无益的,我会说这是其中一种情况。
答案 1 :(得分:9)
我同意Jame的描述,但会添加
只有在想要虚拟地销毁该类的实例时才需要虚拟析构函数。情况并非总是如此,但是如果基本类不打算被破坏,那么它应该防止它
所以我会改变
类的析构函数 用于子类化的应始终 是虚拟的,恕我直言。
这是:
类的析构函数 用于子类化的应该 始终虚拟或受保护。
答案 2 :(得分:4)
有没有正确的方法来解决这个问题?
不要一直使用-Weffc++
。有时打开它来检查你的代码是有用的,但不是真的永久使用它。它给出了误报,而且这些天并没有得到真正的维护。偶尔使用它,但请注意,您可能不得不忽略某些警告。理想情况下,只需记住迈耶斯书中的所有建议,然后无论如何你都不需要它; - )
我认为这个析构函数是虚假的,或者它有真正的目的吗?
不,这不是假的,而且有真正的目的。 如果未定义,则将隐含声明为public
,以防止它明确声明为protected
。