Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么要从中启用\u共享\u这有一个非虚拟析构函数?_C++_Gcc_Boost_C++11_Shared Ptr - Fatal编程技术网

C++ 为什么要从中启用\u共享\u这有一个非虚拟析构函数?

C++ 为什么要从中启用\u共享\u这有一个非虚拟析构函数?,c++,gcc,boost,c++11,shared-ptr,C++,Gcc,Boost,C++11,Shared Ptr,我有一个宠物项目,我用它来试验C++11的新特性。虽然我有C的经验,但我对C++是相当新的。为了将自己训练成最佳实践(除了大量阅读之外),我启用了一些严格的编译器参数(使用GCC4.4.1): 这对我很有效。直到现在,我已经能够解决所有的障碍。但是,我需要从此启用共享,这给我带来了问题。我在编译代码时(可能由-Weffc++触发)收到以下警告(在我的例子中,是错误): base class'class std::enable_shared_from_this'具有非虚拟析构函数 所以基本上,我

我有一个宠物项目,我用它来试验C++11的新特性。虽然我有C的经验,但我对C++是相当新的。为了将自己训练成最佳实践(除了大量阅读之外),我启用了一些严格的编译器参数(使用GCC4.4.1):


这对我很有效。直到现在,我已经能够解决所有的障碍。但是,我需要从此启用共享,这给我带来了问题。我在编译代码时(可能由
-Weffc++
触发)收到以下警告(在我的例子中,是错误):

base class'class std::enable_shared_from_this'具有非虚拟析构函数

所以基本上,我对这个
enable\u shared\u from\u this
的实现有点担心,因为:

  • 用于子类化的类的析构函数应该始终是虚的,IMHO
  • 析构函数是空的,为什么有它呢

  • 我无法想象有人会想通过引用此中的
    enable\u shared\u来删除他们的实例
但我正在寻找解决这个问题的方法,所以我的问题是,有没有合适的方法来解决这个问题?还有:我认为这个析构函数是假的,或者它有真正的用途,这是正确的吗

用于子类化的类的析构函数应该始终是虚的,IMHO

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

在类中包含任何虚函数(包括析构函数)都需要开销。Boost(以及TR1和C++11标准库)不想仅仅因为您需要能够从
这个
指针获得
共享的ptr
而强迫您拥有这种开销

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

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


我无法想象有人会想通过引用此
中的
enable\u shared\u来删除他们的实例

没错


至于编译器警告,我会忽略或抑制它(代码中有一条注释解释为什么这样做)。偶尔,特别是在“迂腐”的警告级别,编译器警告是没有帮助的,我想说这就是其中之一。

我同意Jame的描述,但要补充一点

只有当您希望虚拟销毁该类的实例时,才需要虚拟析构函数。然而,情况并非总是如此,如果基类实际上不打算被销毁,那么它应该对其进行保护

所以我会改变

类的析构函数,该类是 用于子类化的应始终 虚拟一点,伊姆霍

这将是:

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

有没有合适的方法来处理这个问题

不要一直使用
-Weffc++
。有时打开它来检查代码是有用的,但实际上并不是永久使用它。它会产生误报,而且这些天并没有得到真正的维护。时不时地使用它,但请注意,您可能不得不忽略一些警告。理想情况下,只要记住迈尔斯书中的所有建议,你就不需要了;-)

我是否正确地认为这个析构函数是假的,或者它有真正的目的


不,这不是假的,而且有真正的目的如果未定义它,它将被隐式声明为
公共
,以防止它被显式声明为
受保护

Hmm。。说得好。
enable\u shared\u from\u的析构函数实际上是受保护的。因此,这可能是GCC的代码< WEFC++?@ SHTE EF F中的一个bug:有效的C++表示多态碱基应该具有虚拟DRATER,而不打算用于多态的类不应该有虚拟DRANTS。由于编译器无法分辨哪个是哪个,我想说是的,提供此警告是一个bug。所以,如果您在I/IC中实现了关于非多态基类中受保护的DR的建议,如果来自GotW / Excel C++,则不适用。此外,我的GCC人版版本称<>代码> Wnon虚拟DoR 警告仅适用于具有虚拟函数的类。因此,
enable\u shared\u from\u此
具有虚拟功能(我的实现没有),或者警告没有跟随文档(这将是一个bug),或者文档已经更改(检查您的,也许他们会进一步解释警告)。实际上,有可能更新有效的C++——GCC人页引用与我的第三版不匹配的标题。所以可以说这是斯科特·迈尔斯书中的一个错误;-)
enable\u shared\u from\u此
没有虚拟函数,但GCC将在派生类具有虚拟函数时发出警告,而不仅仅是在基类具有虚拟函数时发出警告<代码>-Weffc++
有很多已知的缺陷,包括项目编号指的是旧版本的书籍,其中一些项目被删除或重写以供以后的版本使用,并且警告尚未更新,在某些情况下,它会警告样式而不是正确性,它并不总是有用。
-Wdelete-non-virtual-dtor
选项(源于Clang,我添加到了G++)比
-Wnon-virtual-dtor
更有用。您尝试过私有继承还是受保护继承?它会改变诊断吗?这是个好主意。但不幸的是,它没有。Weffc++
从标准库触发了许多无意义的(与库相关的)警告,不幸的是,提到了这一点,使用g++我们必须关闭整个类的警告。。。这意味着您不会遇到其他潜在问题(包括未初始化的变量成员等潜在错误)
-std=c++0x -Werror -Wall -Winline -Weffc++ -pedantic-errors
base class ‘class std::enable_shared_from_this<Package>’ has a non-virtual destructor