C ++:使用仅具有属性的继承结构时需要实现虚拟析构函数吗?

混蛋

我知道我需要定义一个虚拟析构函数(即使我的类是最好的选择final)。在我的例子中,我使用了类似 C 的结构(没有函数,没有默认值,只有普通成员)并使用继承来组成一个新结构。然后,我将一个指向基类的指针存储在其中,std::unique_ptr并让 RAII 完成其余的工作。

我现在很好奇是否还需要显式添加虚拟析构函数以避免内存问题。

一个例子可能是:

#include <chrono>
#include <memory>

struct A {
    std::chrono::milliseconds duration = std::chrono::milliseconds{-1};
    int count = 0;
};

struct B {
    int mode = 0;
};

struct C : public A, public B {
    int foo = 1;
};

int main()
{
   std::unique_ptr<A> base = std::make_unique<C>();
   base.reset(); // I expect here that A,B and C are destructed properly

   return 0;
}
用户17732522

类是多态的还是微不足道的都没有关系。

如果delete在与它指向的对象的最派生类型不同类型的指针上调用(直到 cv 限定),并且指向的类型没有虚拟析构函数,则行为未定义。

这条规则的一个明显原因是基类子对象可能与最派生对象不在同一个地址。因此编译器无法知道传递给释放函数的偏移量需要是什么。

有人可能会争辩说,如果使用指向第一个基类子对象的指针,则具有普通析构函数的标准布局类不需要遵循此规则,但标准没有例外,并且您的类C不是标准布局反正。

请参阅CWG 问题 1259作为非缺陷关闭。问题中提到的大小感知全局释放函数也是在 C++14 中引入的,这是使用基类指针在实践中可能会给您带来问题的另一个原因,即使析构函数是微不足道的并且地址没有偏移。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

没有虚拟析构函数的C ++继承

具有外部无法解析的C ++虚拟析构函数

当基类的成员的析构函数具有非空的no指定符和主体时,在析构函数上使用C2694

C ++:具有成员的抽象类中的纯虚拟析构函数

C ++继承类。将使用哪个析构函数?

C ++虚拟继承,虚拟析构函数和dynamic_cast <void *>

非虚拟析构函数c ++的异常

C ++中的纯虚拟析构函数

C ++虚拟析构函数-内存泄漏

C ++中的原始类型是否具有析构函数?

如何允许 std::unique_ptr 访问类的私有析构函数或使用私有析构函数实现 C++ 工厂类?

c++ 使用链表时的析构函数段错误

为什么我们需要C ++中的纯虚拟析构函数?

这个C ++析构函数是多余的吗?

没有析构函数的C ++函数

是否需要在C ++析构函数中明确销毁结构中固定大小的数组?

当您具有二维数组(在C ++中)时,调用析构函数的正确方法是什么?

C ++。在析构函数中调用虚拟成员函数

在C ++中,是否有一种(新的)方法可以在不实例化实例的情况下测试类在模板中是否具有虚拟析构函数?

C ++使用RAII与引发的析构函数

C ++ Qt基类虚拟析构函数

如何使虚拟析构函数在C ++中被调用?

C ++ 11接口纯虚拟析构函数

C ++切片和虚拟析构函数

在C ++中调用虚拟析构函数的顺序

C ++派生类和虚拟析构函数

在多级继承中调用析构函数(C ++)

C ++放置新功能,继承和析构函数

关于结构构造函数和析构函数的行为-C ++