【问题标题】:Do I need to implement my own destructors for my derived classes if they don't contain static data?如果派生类不包含静态数据,我是否需要为派生类实现自己的析构函数?
【发布时间】:2014-12-01 00:37:52
【问题描述】:

假设我有:

class Base {
public:
    virtual ~Base() = 0;
}

class Derived: public Base {
public:
    ~Derived();
}

在我的代码中,我需要通过 Base 指针删除 Derived 类,如下所示:

delete[] pt_base;

但是,在已实现的析构函数中,我实际上没有要销毁的东西。但是我仍然需要他们通过基类删除?

在没有大量浪费代码和空析构函数的情况下实现我想要的最佳方法是什么?

【问题讨论】:

    标签: c++ polymorphism destructor virtual-destructor


    【解决方案1】:

    不,Base 类的虚拟析构函数声明/定义就足够了,但将其抽象化需要您在 Derived 类中提供此析构函数。

    如果你只是声明

    class Base {
    public:
        virtual ~Base() {} // <<< Have a definition
    };
    

    您不需要在继承的类中指定任何析构函数。

    【讨论】:

    • "虚拟构造函数"??
    • Np。顺便说一句,你喜欢我的标准引用吗?
    • @LightnessRacesinOrbit 这是来自c++11 的所有引用。尽管您当然适合当前的标准(我很高兴跟上这一标准),但我在答案中发布的内容在过去几十年中对我有用吗?现在无效了吗?
    • 嗯? C++11 有什么问题?如果您愿意,我可以发布 C++03 和 C++14 中的等效措辞。
    • 这个“解决方案”完全改变了程序,使Base 不再是一个接口。不知道为什么它的投票率如此之高。
    【解决方案2】:

    如果你想提供一个带有“默认”实现的析构函数,那么default 关键字就是为了这个目的而提供的。它会导致用户声明的析构函数与隐式定义的析构函数具有相同的行为。

    class Derived : public Base {
    public:
        ~Derived() = default;
    }
    

    这相当于提供一个像{} 这样的空析构函数体,但可以更好地显示您的意图。

    但是,不,您不需要提供这些析构函数:

    [C++11: 12.4/4]: 如果一个类没有用户声明的析构函数,则析构函数被隐式声明为默认 (8.4)。 隐式声明的析构函数是其类的 inline public 成员。

    [C++11: 12.4/5]:X 类的默认析构函数在以下情况下定义为已删除:

    • X 是一个类似联合的类,它有一个变体成员和一个非平凡的析构函数,
    • 任何非静态数据成员的类类型为 M(或其数组),并且 M 具有已删除的析构函数或无法从默认析构函数访问的析构函数,
    • 任何直接或虚拟基类都具有已删除的析构函数或无法从默认析构函数访问的析构函数,
    • 或者,对于虚拟析构函数,查找非数组解除分配函数会导致歧义,或者导致函数从默认析构函数中删除或无法访问。

    [..]

    这些规则都不适用于这里,并且在基类具有纯或不纯虚拟析构函数的情况下不存在改变这种行为的规则,因此我上面示例中隐式声明的析构函数不会被删除(即有效) .

    以下措辞是可以为您声明派生析构函数的另一个有力线索:

    [C++11: 12.4/9]: 析构函数可以声明为virtual (10.3) 或纯virtual (10.4);如果在程序中创建了该类或任何派生类的任何对象,则应定义析构函数。 如果一个类有一个带有虚拟析构函数的基类,那么它的析构函数(无论是用户声明的还是隐式声明的)都是virtual


    不幸的是,如果您希望析构函数是纯的,您将无法将 default 用于 Base 类;您仍然需要单独提供其 [empty] 定义:

    class Base {
    public:
        virtual ~Base() = 0;
    };
    
    Base::~Base() {}
    

    【讨论】:

      猜你喜欢
      • 2019-10-11
      • 1970-01-01
      • 2012-02-14
      • 2021-08-22
      • 1970-01-01
      • 2013-06-02
      • 2016-01-18
      • 2016-03-09
      • 1970-01-01
      相关资源
      最近更新 更多