首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >虚拟析构函数是继承的吗?

虚拟析构函数是继承的吗?
EN

Stack Overflow用户
提问于 2010-02-04 17:00:55
回答 5查看 26.4K关注 0票数 83

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

代码语言:javascript
复制
class base {
public:
    virtual ~base () {}
};

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

具体问题:

  1. 是1)和2)相同吗?2)是因为它的基础而自动为虚的,还是它“停止”了派生析构函数,如果没有做什么就省略它?
  2. 声明派生析构函数的最佳实践是什么?
  3. 将其声明为虚拟的、非虚拟的或在可能的情况下忽略它?
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-02-04 17:04:14

  1. 是的,它们是一样的。派生类没有声明虚的东西并不能阻止它成为虚的。事实上,如果派生类中的任何方法(包括析构函数)在基类中是虚的,那么就没有办法阻止它成为虚的。在>=C++11中,您可以使用final来防止它在派生类中被重写,但这并不能阻止它是虚的。
  2. 是的,如果派生类中的析构函数没有任何作用,则可以省略它。不管它是不是虚拟的,

  1. ,如果可能的话,我会省略它。为了清楚起见,我总是对派生类中的虚函数使用virtual关键字或override。人们不应该在继承层次结构中一直往上爬才能知道函数是虚的。此外,如果您的类是可复制或可移动的,而不必声明自己的复制或移动构造函数,则声明任何类型的析构函数(即使您将其定义为default)都会强制您声明复制和移动构造函数以及赋值运算符(如果需要的话),因为编译器将不再为您放置它们。

注释中指出,如果析构函数未声明,编译器会生成一个默认析构函数(也就是仍然是虚拟的)。这个默认函数是一个内联函数。

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

我个人的选择仍然是在可能的情况下忽略它。在我看来,它弄乱了代码,编译器有时可以用默认实现而不是空实现来做一些更有效的事情。但是,你可能会受到一些限制,这使得这不是一个好的选择。

票数 97
EN

Stack Overflow用户

发布于 2010-02-04 17:06:40

与所有方法一样,

  1. 析构函数自动是虚拟的。你不能阻止一个方法在C++中成为虚拟的(如果它已经被声明为虚拟的,也就是说,在Java语言中没有‘

’的等价物)

  1. 是的,它可以被省略。
  2. 如果我想让这个类被子类化,我会声明一个虚拟析构函数,无论它是不是另一个类的子类化,我也更喜欢继续声明方法是虚拟的,即使它不是必需的。这将保持子类的工作,如果你曾经决定删除继承。但我想这只是一个风格问题。
票数 2
EN

Stack Overflow用户

发布于 2010-02-04 17:04:25

虚成员函数将隐式地使此函数的任何重载都是虚的。

所以1)中的虚函数是“可选的”,基类析构函数是虚的,使得所有子析构函数也都是虚的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2198379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档