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

Sté*_*hen 18 c++ gcc boost shared-ptr c++11

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

-std=c++0x -Werror -Wall -Winline -Weffc++ -pedantic-errors
Run Code Online (Sandbox Code Playgroud)

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

base class ‘class std::enable_shared_from_this<Package>’ has a non-virtual destructor
Run Code Online (Sandbox Code Playgroud)

所以基本上,我对这个实现有点疑虑enable_shared_from_this,因为:

  • 这是一个类的析构函数预期为子类应该始终是虚拟的,恕我直言.
  • 析构函数是空的,为什么要它呢?
  • 我无法想象有人会想通过引用删除他们的实例enable_shared_from_this.

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

Jam*_*lis 25

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

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

在类中包含任何虚函数(包括析构函数)都需要开销.Boost(以及TR1和C++ 11标准库)不希望强迫您只是因为需要能够shared_ptrthis指针获取a而产生这种开销.

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

如果您没有用户定义的构造函数,编译器会为您提供一个构造函数,因此它并不重要.

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

究竟.

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


iai*_*ain 9

我同意Jame的描述,但会补充一下

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

所以我会改变

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

这是:

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

  • @Shtééf:有效的C++说多态基础应该有虚拟的dtors,而不是用于多态的类不应该有虚拟的dtors.由于编译器无法分辨哪个是哪个,我会说是的,提供此警告是一个错误.因此,如果从GotW/Exceptional C++开始,对IIRC的非多态基类中的受保护dtors的建议要么是有效的. (2认同)
  • 此外,我的gcc手册页版本说`-Wnon-virtual-dtor`警告仅适用于具有虚函数的类.所以`enable_shared_from_this`有一个虚函数(我的实现没有),或者警告没有遵循文档(这将是一个bug),或者文档已经改变(检查你的,也许他们解释警告进一步).实际上,有效的C++*可能已经更新 - gcc手册页引用了与我的第3版不匹配的标题.可以说这是Scott Meyers的书中的一个错误;-) (2认同)