Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.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++ 虚拟析构函数用例_C++_C++11_Undefined Behavior_Virtual Functions_Class Hierarchy - Fatal编程技术网

C++ 虚拟析构函数用例

C++ 虚拟析构函数用例,c++,c++11,undefined-behavior,virtual-functions,class-hierarchy,C++,C++11,Undefined Behavior,Virtual Functions,Class Hierarchy,我读过一些文章,正如他们所说,主要的虚拟析构函数用例有: 派生类可以从堆中动态分配数据,即“拥有”该数据对象。所以,他们需要在析构函数中执行一些删除例程。通过base类指针删除需要virtual在所有派生的类中声明析构函数,直到那些具有动态数据分配的类(base类也需要它) 此类具有虚拟方法。但这对我来说并不清楚。仅通过base类指针调用virtual方法,总是会导致大多数派生的实现调用。他们唯一的排除规则是施工阶段。从字面上讲,在期间,此对象还不是派生的类型,即使以后会是。好的,那破坏阶段呢

我读过一些文章,正如他们所说,主要的虚拟析构函数用例有:

  • 派生类可以从堆中动态分配数据,即“拥有”该数据对象。所以,他们需要在析构函数中执行一些删除例程。通过base类指针删除需要
    virtual
    在所有派生的类中声明析构函数,直到那些具有动态数据分配的类(base类也需要它)

  • 此类具有
    虚拟
    方法。但这对我来说并不清楚。仅通过base类指针调用
    virtual
    方法,总是会导致大多数派生的实现调用。他们唯一的排除规则是施工阶段。从字面上讲,在
    期间,此
    对象还不是派生的类型,即使以后会是。好的,那破坏阶段呢?据我所知,规则是倒序的。不管怎样,层次结构中某个类的析构函数是否声明为
    virtual
    ,在每个析构函数
    期间,此
    指针的使用都与此类类型的指针相同,因为
    virtual
    d-r,任何派生类都已被销毁,或者未被销毁(在某些设计中,这假设是可以的)。也许是这样,为什么d-r必须是虚拟的?Vtable将有派生的类的条目,从d-r调用一些基本类中的
    虚拟
    方法将导致UB?好的,但这个规则只适用于这个类在d-r中调用一些
    virtual
    方法,并且它们在派生的类中确实有实现的情况

我的观点是,也可能存在这样一种情况:没有动态数据分配,所有层次结构中都没有虚拟方法,但派生的析构函数在删除时可能会执行一些关键任务(同步、解锁等)。我们需要基类中的虚拟d-r。这种情况可能是设计不好的结果


但无论如何,某些公共类的开发人员不能100%知道派生类是否会在d-r中使用某些虚拟方法,或者分配动态数据。那么,我说的对吗,任何未声明为
final
的公共类都必须声明d-r为virtual?只有
final
关键字才能保证指向此类的任何指针始终为该类型,因此可以安全地非虚拟删除。

如果通过指向基类的指针删除派生对象,则(并且只有在那时)基类析构函数必须是虚拟的。否则就是。没有其他相关规则

如果这个类有一个虚拟函数,那么就不会引入开销。如果类没有任何其他虚拟函数,则基类设计器必须考虑添加虚拟析构函数的运行时惩罚之间的交易,而不是类的用户可能试图通过基类指针删除派生对象的风险。

如果通过指向基类的指针删除派生对象,那么(并且只有在那时)基类析构函数必须是虚拟的。否则就是。没有其他相关规则

如果这个类有一个虚拟函数,那么就不会引入开销。如果类没有任何其他虚拟函数,则基类设计器必须考虑添加虚拟析构函数的运行时惩罚之间的交易,而不是类的用户可能试图通过基类指针删除派生对象的风险。

Related:不。类本身在内部做什么或包含什么是完全无关的。唯一的标准是如何使用它。如果要通过基指针删除派生类对象,则基类必须具有虚拟析构函数。并没有更多,也并没有更少。但开发人员不能确定基类指针作为派生类指针的用法,其他开发人员将这样做,并以这种方式使用。所以,同样,基类开发人员应该将d-r声明为虚拟的。我没有听说过太多关于开发人员使用
std::vector
,或者90%以上的标准库类进行开发的故事。当这种情况偶尔发生时,开发人员很快就会被拍打手腕,并学会不再这样做。类作者应记录预期用途。他们不需要为非预期用途提供保护。好的,我知道了,谢谢!相关:不。类本身在内部做什么或包含什么完全无关。唯一的标准是如何使用它。如果要通过基指针删除派生类对象,则基类必须具有虚拟析构函数。并没有更多,也并没有更少。但开发人员不能确定基类指针作为派生类指针的用法,其他开发人员将这样做,并以这种方式使用。所以,同样,基类开发人员应该将d-r声明为虚拟的。我没有听说过太多关于开发人员使用
std::vector
,或者90%以上的标准库类进行开发的故事。当这种情况偶尔发生时,开发人员很快就会被拍打手腕,并学会不再这样做。类作者应记录预期用途。他们不需要为非预期用途提供保护。好的,我知道了,谢谢!好的,谢谢,我现在明白了。因此,我的建议基本上是正确的,开发人员决定这一点的基础是希望用户是一个好用户,或者不是@ЯЯааааааааааааааааа(无论如何,这可能是个坏主意,当没有虚拟函数时,没有理由这样做)如果设计器在删除时使用基类指针,但具有非虚拟d-r-这意味着,该基类根本不应该用作基类,是吗?@如果设计器不包含虚拟析构函数,则生成