gpt4 book ai didi

c++ - 虚拟析构函数是继承的吗?

转载 作者:IT老高 更新时间:2023-10-28 12:06:09 26 4
gpt4 key购买 nike

如果我有一个带有虚拟析构函数的基类。是否也有派生类来声明虚析构函数?

class base {
public:
virtual ~base () {}
};

class derived : base {
public:
virtual ~derived () {} // 1)
~derived () {} // 2)
};

具体问题:

  1. 1) 和 2) 一样吗? 2) 是因为它的基础而自动虚拟还是“停止”虚拟?
  2. 派生的析构函数如果无关的话可以省略吗?
  3. 声明派生析构函数的最佳做法是什么?声明它是虚拟的、非虚拟的还是尽可能省略它?

最佳答案

  1. 是的,它们是一样的。派生类没有声明一些虚拟的东西并不能阻止它成为虚拟的。事实上,如果派生类中的任何方法(包括析构函数)在基类中是虚拟的,则无法阻止它成为虚拟方法。在 >=C++11 中,您可以使用 final 来防止它在派生类中被覆盖,但这并不妨碍它成为虚拟的。
  2. 是的,派生类中的析构函数如果无关,可以省略。而且它是否是虚拟的并不重要。
  3. 如果可能,我会省略它。为了清楚起见,我总是在派生类中使用 virtual 关键字或 override 来表示虚函数。人们不应该一直走上继承层次结构来确定一个函数是虚拟的。此外,如果您的类是可复制或可移动的,而无需声明您自己的拷贝或移动构造函数,则声明任何类型的析构函数(即使您将其定义为 default)都会强制您声明拷贝并如果需要,请移动构造函数和赋值运算符,因为编译器将不再为您放入它们。

作为第 3 项的一个小点。注释中已经指出,如果未声明析构函数,编译器会生成一个默认析构函数(仍然是虚拟的)。而那个默认的就是一个内联函数。

内联函数可能会将您的程序的更多部分暴露给程序其他部分的更改,并使共享库的二进制兼容性变得棘手。此外,面对某些类型的更改,增加的耦合会导致大量的重新编译。例如,如果您决定确实需要虚拟析构函数的实现,那么调用它的每一段代码都需要重新编译。而如果您在类主体中声明它,然后在 .cpp 文件中将其定义为空,则无需重新编译即可更改它。

我个人的选择仍然是尽可能省略它。在我看来,它会使代码变得困惑,并且编译器有时可以使用默认实现而不是空的实现稍微更有效的事情。但是,您可能会受到一些限制,这会使其成为一个糟糕的选择。

关于c++ - 虚拟析构函数是继承的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2198379/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com