【问题标题】:Inheritance in c++ : destructorsc++中的继承:析构函数
【发布时间】:2021-04-13 07:58:44
【问题描述】:

我在每个派生类使用的抽象基类中添加了一个受保护的成员数组,基类的析构函数应该是虚的还是可以的:

**~base(){
   delete[] array;
}**

【问题讨论】:

  • 抽象基类的析构函数应该总是虚的。
  • 为什么是“或”? delete[] 必须在~base() 析构函数中,与你要不要virtual 无关。
  • 不要在现代 C++ 中显式使用 newdelete!使用std::vectorstd::unique_ptrstd::shared_ptr 和其他类似的 RAII 模式。
  • 我们不允许使用 STL 中的任何东西

标签: c++ class inheritance destructor virtual-destructor


【解决方案1】:

两者都有!

您可以为基础析构函数提供定义(即使它是纯虚拟的!),如果基础是资源所在的位置,那么基础就是应该清理它的位置。


或者,给自己找个不错的std::vector,这样一切都为你完成了。

【讨论】:

  • 非常感谢您的帮助!我所做的是我用 delete[] 在基类中定义了一个析构函数,但我得到了 SIGTRAP
  • @AdanSuleiman 这是一些不相关的问题,如果没有您的minimal reproducible example,我们将无法解决。
【解决方案2】:

我在抽象基类中添加了一个受保护的成员数组,每个 派生类使用,基类的析构函数是否应该是虚拟的

是的。

当你使用多态时,析构函数也应该是虚拟的。

对此有官方指南:

CppCoreGuidelines/CppCoreGuidelines.md at master · isocpp/CppCoreGuidelines · GitHub

C.127:具有虚函数的类应该有一个虚或受保护的析构函数

原因

具有虚函数的类通常(并且通常)通过指向基的指针来使用。通常,最后一个用户必须在指向基址的指针上调用 delete,通常是通过指向基址的智能指针,因此析构函数应该是公共的和虚拟的。不太常见的是,如果不支持通过指向基址的指针进行删除,则析构函数应该是受保护的并且是非虚拟的;见C.35

例子,不好
struct B {
    virtual int f() = 0;
    // ... no user-written destructor, defaults to public non-virtual ...
};

// bad: derived from a class without a virtual destructor
struct D : B {
    string s {"default"};
};

void use()
{
    unique_ptr<B> p = make_unique<D>();
    // ...
} // undefined behavior, might call B::~B only and leak the string
笔记

有些人不遵守这条规则,因为他们打算只通过shared_ptr 使用一个类:std::shared_ptr&lt;B&gt; p = std::make_shared&lt;D&gt;(args); 这里,共享指针将负责删除,因此不会因不适当的@ 而发生泄漏987654326@的基地。一直这样做的人可能会得到误报,但规则很重要——如果使用make_unique 分配一个怎么办?除非B 的作者确保它永远不会被滥用,否则它是不安全的,例如通过将所有构造函数设为私有并提供工厂函数来强制使用make_shared 进行分配。

执法
  • 具有任何虚函数的类应该有一个析构函数,该析构函数要么是公共的和虚拟的,要么是受保护的和非虚拟的。
  • 带有虚函数但没有虚析构函数的类的标志delete

【讨论】:

    猜你喜欢
    • 2012-04-28
    • 2011-12-31
    • 2011-10-14
    • 2012-11-14
    • 1970-01-01
    • 2023-03-30
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多