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

C++ 派生类中是否需要显式声明的析构函数?,c++,virtual,destructor,C++,Virtual,Destructor,考虑以下代码段: 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? } 我可以很容易地找到关于基类析构函数的信息,例如 “通过指向基的指针删除

考虑以下代码段:

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?
}
我可以很容易地找到关于基类析构函数的信息,例如

“通过指向基的指针删除对象会调用未定义的行为 除非基类中的析构函数是虚的 准则是基类的析构函数必须是public或public 虚拟的、受保护的和非虚拟的”

基类中的虚拟析构函数是必须的,派生类的析构函数如何,它们是否必须显式声明/定义?我发现它相当混乱,因为派生类的析构函数也自动是虚拟的。就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?
}

不,不需要申报;从具有声明为
virtual
的给定函数的类继承的类不需要将其继承的形式声明为
virtual
即可成为
virtual
。这包括隐式声明的析构函数。

不需要在派生类中显式定义析构函数。根据C++标准

如果一个类有一个带有虚拟析构函数的基类,那么它的析构函数 (无论是用户声明还是隐式声明)都是虚拟的

另外,如果你担心访问控制,那么

隐式声明的析构函数是其 班级

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

对于代码的可读性,您可以编写例如

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

正如其他人所说,不,您不需要在子类中声明不做任何事情的析构函数,因为它是从祖先类继承下来的

但是,请记住,您的类C可能是从VendorBAwesomeness.dll中的某个第三方库类B派生的,而B又可能是从mswonderful.dll中的Microsoft类A派生的

如果你想对你的类的读者和用户友好,你应该考虑在C类中指定<代码>虚拟,因为你在阅读B类的界面时看到了它,B类的作者在学习A类

时也做了同样的事情。
通过向下传递这些信息,您可以让其他人清楚地看到您的代码所做的事情,而不必四处寻找信息。

C++不会强迫您编写什么都不做的代码。你必须自己断掉最后的结果,这只能是一个宏,假装C++与java有关系。Override是一个有价值的C++11添加项。只是不是在析构函数上,你不能像在另一个虚拟方法上一样摸索它。编写健全的C++代码,所有的东西都容易组合在一起。