【问题标题】:How/when do I use a virtual destructor?如何/何时使用虚拟析构函数?
【发布时间】:2011-05-20 01:28:21
【问题描述】:

我目前正在编写一个具有以下多态层次结构的程序: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()'

我的语法有什么问题?感谢您能给我的任何帮助。

【问题讨论】:

    标签: c++ inheritance polymorphism destructor


    【解决方案1】:

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

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

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

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

    【讨论】:

    • +1 以获得很好的答案,同时也解释了“为什么”部分!谢谢!
    【解决方案2】:

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

    ~Complex();
    

    注意 virtual 在这里是可选的。析构函数将是虚拟的,因为基的析构函数是虚拟的。

    【讨论】:

      【解决方案3】:

      什么时候声明一个虚拟的析构函数?

      我建议你按照这个算法来决定你是否应该声明一个虚拟的析构函数。

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

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

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

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

      是否允许通过基指针进行多态删除?

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

      参考资料:

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

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

      【讨论】:

        【解决方案4】:

        我的语法有什么问题?

        以下内容:

        在我所有的派生类中,我 有这个:

        Rational::~Rational() { }

        不,你没有。你不是为了Complex

        【讨论】:

          【解决方案5】:

          问题是:什么时候不声明析构函数为虚拟的?声明一个虚拟的析构函数没有任何缺点。

          【讨论】:

            猜你喜欢
            • 2022-01-01
            • 1970-01-01
            • 2019-06-26
            相关资源
            最近更新 更多