请考虑以下代码段:
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 回答
正如其他人所说,不,你不需要在后代类中声明一个do-nothing析构函数,因为它从祖先类中继承下来 .
但是,请记住,您的C类可能来自某些第三方库B类,例如VendorBAwesomeness.dll,而B可能又来自Microsoft的mswonderful.dll中的A类 .
如果你想对你的类的读者和用户好一点,你应该考虑在你的C类中指定
virtual
,因为你在阅读它时在B类的界面中看到它,而B类的作者在他/她了解了A班 .通过传递这些信息,您可以让其他人清楚地看到您的代码所做的事情,而无需他们不得不寻找信息 .
无需在派生类中明确定义析构函数 . 根据C标准
此外,如果您打扰访问控制
编译器将其隐式定义的析构函数的地址放在vtable中 . 因此派生类的vtable将存储派生类的析构函数的地址 .
为了您的代码的可读性,您可以编写例如
不,它不需要声明;从具有声明为
virtual
的给定函数的类继承的类不需要将其继承的表单声明为virtual
,因为它是virtual
. 这包括隐式声明的析构函数 .