首页 文章

派生类中是否需要显式声明析构函数?

提问于
浏览
3

请考虑以下代码段:

class A
{
virtual void function();
public:
  virtual ~A() {};
}

class B: public A
{
virtual void function() override final;
public:
  /*virtual*/ ~B() {}; // does this d-tor have to be declared at all?
}

我可以很容易地找到关于基类析构函数的信息,例如http://en.cppreference.com/w/cpp/language/destructor

“通过指向base的指针删除对象会调用未定义的行为,除非基类中的析构函数是虚拟的 . 一个常见的指导原则是基类的析构函数必须是公共的,虚拟的或受保护的,非虚拟的”

基类中的虚拟析构函数是必须的,派生类的析构函数如何,是否必须显式声明/定义?我发现它很混乱,因为派生类的析构函数也是自动虚拟的 . 在vtable寻址方面跳过派生类的析构函数的声明/定义是否合法?以下情况如何:

class A
{
virtual void function();
public:
  virtual ~A() {};
}

class B: public A
{
virtual void function() override;
public:
  /*virtual*/ ~B() {}; // does this d-tor have to be declared at all?
}

class C: public B
{
virtual void function() override final;
public:
  /*virtual*/ ~C() {};  // does this d-tor have to be declared at all?
}

3 回答

  • 3

    正如其他人所说,不,你不需要在后代类中声明一个do-nothing析构函数,因为它从祖先类中继承下来 .

    但是,请记住,您的C类可能来自某些第三方库B类,例如VendorBAwesomeness.dll,而B可能又来自Microsoft的mswonderful.dll中的A类 .

    如果你想对你的类的读者和用户好一点,你应该考虑在你的C类中指定 virtual ,因为你在阅读它时在B类的界面中看到它,而B类的作者在他/她了解了A班 .

    通过传递这些信息,您可以让其他人清楚地看到您的代码所做的事情,而无需他们不得不寻找信息 .

  • 5

    无需在派生类中明确定义析构函数 . 根据C标准

    如果类具有带虚拟析构函数的基类,则其析构函数(无论是用户还是隐式声明)都是虚拟的

    此外,如果您打扰访问控制

    隐式声明的析构函数是其类的内联公共成员 .

    编译器将其隐式定义的析构函数的地址放在vtable中 . 因此派生类的vtable将存储派生类的析构函数的地址 .

    为了您的代码的可读性,您可以编写例如

    class B: public A
    {
    virtual void function() override final;
    public:
      virtual ~B() = default;
    }
    
  • 0

    不,它不需要声明;从具有声明为 virtual 的给定函数的类继承的类不需要将其继承的表单声明为 virtual ,因为它是 virtual . 这包括隐式声明的析构函数 .

相关问题