【问题标题】:Do I need to define a virtual destructor even if the base and derived class only use primitive data types?即使基类和派生类仅使用原始数据类型,我是否需要定义虚拟析构函数?
【发布时间】:2019-10-25 22:17:38
【问题描述】:

根据 C++ 标准:5.3.5/4:

如果[删除运算符]的操作数的静态类型是 与其动态类型不同,静态类型应为基类 操作数的动态类型和静态类型应具有虚拟 析构函数或行为未定义。

这是否适用于以下情况:

class B
{
    public:
    virtual void f() const = 0;
    virtual void g() = 0;
};

class D : public B
{
    public:
    explicit D(int x) : x_ {x} {}

    void f() const override;
    void g() override;

    private:
    int x_;
};

在这种情况下,D 和 B 都没有要释放的东西,所以它不应该不再需要提供虚拟析构函数吗?或者这仍然是未定义的行为?

【问题讨论】:

  • 只要按照标准所说的,如果动态类型不同并且你没有虚拟析构函数,那么它就是UB。试图看看这个 UB 如何或应该是无害的是无关紧要的。
  • 如果你delete一个D到B*的实例,B需要有一个多态析构函数。
  • 编译器可能认为 UB 路径不可达,因此不会生成该路径代码。

标签: c++


【解决方案1】:

您引用的标准中的该声明意味着一个示例(使用您的课程BD

int main()
{
    B *object = new D;
    delete object;
}

如果B 没有virtual 析构函数,则具有未定义的行为。

该规则没有例外。

类(或其成员函数)做什么或不做什么并不重要。 B 中的非虚拟析构函数导致删除表达式 (delete object) 具有未定义的行为。没有例外。

【讨论】:

    【解决方案2】:

    该标准不会根据类的内容做出任何例外。

    我会说,“是的,你需要 virtual 析构函数。”

    【讨论】:

      猜你喜欢
      • 2021-08-22
      • 2015-02-24
      • 2021-01-31
      • 2016-11-20
      • 2012-09-01
      • 2017-12-18
      • 2015-04-16
      • 2011-08-02
      • 2018-07-06
      相关资源
      最近更新 更多