繁体   English   中英

我何时/何时使用虚拟析构函数?

[英]How/when do I use a virtual destructor?

我目前正在编写一个具有以下多态层次结构的程序:Base:Multinumber。 派生:对,复杂,理性。 Multinumber是一个虚拟类,从不实例化。

在我的程序过程中,我经常动态管理基类,所以我需要一个析构函数。 我的问题是:如何使析构函数虚拟化? 在我的Multinumber.h文件中,我现在有:

  virtual ~Multinumber();

在我的Multinumber.cpp中:

Multinumber::~Multinumber()
{
}

在我的所有派生类中,我都有:

Rational::~Rational()
{
}

我的任何derived.h文件中都没有任何内容。 不幸的是,这不编译。 相反,我得到这个错误:

Complex.cpp|75|error: definition of implicitly-declared 'virtual Complex::~Complex()'

我的语法有什么问题? 感谢你给与我的帮助。

只是声明基础中的virtual析构函数,并给它空定义就足够了。 对于其他类,您根本不需要做任何事情,除非这些析构函数的实际工作要做。

基类中virtual声明的要点是确保可以多态调用析构函数(以便Base* d = new Derived(); delete d;正常工作,调用Derived析构函数而不是Base析构函数)。 然后,您必须定义该析构函数(即使它不起作用),因为您声明了它。

但是,对于所有派生类,如果未指定任何内容,则会为它们生成默认的“成员和基础的调用析构函数”析构函数,并且一切都可以根据需要进行操作。 除非你再次需要做任何其他事情来正确地破坏对象。

正如Dark Falcon所指出的那样,你需要在基础上为你定义的每个成员做一个声明,包括析构函数。 因此,如果您确实编写了Complex ::〜Complex,那么它必须在Complex类定义中声明,即使您从声明和定义析构函数的类继承。 (析构函数,就像构造函数一样,实际上并不是继承的;默认的“在成员和基础上递归调用”行为并不是真的相同。这些函数是特殊的,因为它们管理对象的生命周期,而不是使用对象。 )

在Complex类中,您还需要声明析构函数:

~Complex();

请注意,虚拟是可选的。 析构函数将是虚拟的,因为base的析构函数是虚拟的。

何时声明析构函数是虚拟的?

我建议您按照此算法来决定是否应该声明析构函数是否为虚拟。

您的课程是否打算用作基类?

  • 否:声明非虚拟析构函数(避免在类的每个对象上使用v指针)并记住不要从具体类派生。
  • 是的:转到下一个问题。

你的基类是抽象的吗? (即任何虚拟纯方法?)

  • 否:尝试通过重新设计层次结构[1]来使您成为基类抽象(即不允许基类实例化)。
  • 是的:转到下一个问题。

你想通过基指针允许多态删除吗?

  • 否:声明受保护的虚拟析构函数以避免不必要的使用。
  • 是:声明公共虚拟析构函数(在这种情况下没有开销)。

参考文献:

[1]:S。迈耶斯。 更有效的C ++,第33项(Addison-Wesley,1996)。

[2]:“虚拟” http://www.gotw.ca/publications/mill18.htm

问题是:何时不声明析构函数是虚拟的? 声明析构函数virtual没有任何缺点。

我的语法有什么问题?

下列:

在我的所有派生类中,我都有:

Rational :: ~Rational(){}

不,你没有。 你没有为Complex做这件事。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM