我目前正在编写一个具有以下多态层次结构的程序:Base:Multinumber。派生:对,复杂,理性。 Multinumber是一个虚拟类,从不实例化。
在我的程序过程中,我经常动态管理基类,所以我需要一个析构函数。我的问题是:如何使析构函数虚拟化?在我的Multinumber.h文件中,我现在有这个:
virtual ~Multinumber();
在我的Multinumber.cpp中:
Multinumber::~Multinumber()
{
}
在我的所有派生类中,我都有:
Rational::~Rational()
{
}
我的任何deri.h文件中都没有任何内容。不幸的是,这不编译。相反,我得到了这个错误:
Complex.cpp|75|error: definition of implicitly-declared 'virtual Complex::~Complex()'
我的语法有什么问题?谢谢你能给我的任何帮助。
答案 0 :(得分:4)
在基数中声明virtual
析构函数,并为其赋予空定义就足够了。对于其他课程,你根本不需要做任何事情,除非那些析构函数的实际工作要做。
基类中virtual
声明的要点是确保可以多态调用析构函数(以便Base* d = new Derived(); delete d;
正常工作,调用派生析构函数而不是Base析构函数)。然后,您必须定义该析构函数(即使它不起作用),因为您声明了它。
但是,对于所有派生类,如果您没有指定任何内容,则会为它们生成默认的“成员和基础的调用析构函数”析构函数,并且一切都按您的需要工作。除非你再次需要做任何其他事情来正确破坏对象。
正如Dark Falcon指出的那样,你需要在基础上为你定义的每个成员做一个声明,包括析构函数。因此,如果您确实编写了Complex ::〜Complex,那么它必须在Complex类定义中声明,即使您从声明和定义析构函数的类继承。 (析构函数,就像构造函数一样,实际上并不是继承的;默认的“在成员和基础上递归调用”行为并不是真的相同。这些函数是特殊的,因为它们管理对象的生命周期,而不是使用对象。 )
答案 1 :(得分:3)
在Complex类中,您还需要声明析构函数:
~Complex();
请注意,虚拟是可选的。析构函数将是虚拟的,因为base的析构函数是虚拟的。
答案 2 :(得分:2)
我建议您按照此算法来决定是否应该声明析构函数是否为虚拟。
您的课程是否打算用作基类?
您的基类是抽象的吗? (即任何虚拟纯方法?)
您是否希望通过基指针允许多态删除?
参考文献:
[1]:S。Meyers。更有效的C ++,第33项(Addison-Wesley,1996)。
答案 3 :(得分:0)
我的语法有什么问题?
以下内容:
在我的所有派生类中,我 有这个:
Rational :: ~Rational(){}
不,不。您没有为Complex
执行此操作。
答案 4 :(得分:0)
问题是:何时不声明析构函数是虚拟的?声明析构函数虚拟没有任何缺点。