【问题标题】:need to call the base destructor method from a derived class in c++? [duplicate]需要从 C++ 中的派生类调用基析构函数方法? [复制]
【发布时间】:2011-07-29 21:59:17
【问题描述】:

请考虑以下事项

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

class derived : public base{

};

当派生对象被析构并且派生类没有定义析构函数时,是否会自动调用基类析构函数?

否则,如果我在派生类中也有析构函数,我是否也需要显式调用基类析构函数?

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

class derived : public base{
     derived();
     ~derived
           base::~base(); //do I need this?
     }
};

【问题讨论】:

  • 不,你不需要这样做——它是自动的
  • 请注意,您可以通过简单的实验来回答这个问题,方法是在基本析构函数中打印一些内容。
  • @Beta:你是对的。但我更喜欢对这个主题有一个完整的解释。事实上,现在我意识到我应该在基类中声明我的虚拟析构函数。如果我只是尝试使用 print 语句,我不会意识到这一点,因为实际上我没有在基类引用上调用任何析构函数。

标签: c++ destructor derived-class base-class


【解决方案1】:

在这种情况下会自动调用基类析构函数; you do not need to call it.

但是,请注意当通过基类指针上的delete 销毁对象并且析构函数不是virtual 时,结果将是未定义的行为(尽管您可能不会得到崩溃)。

在任何要派生的类中始终将析构函数声明为virtual。如果基类不需要有析构函数,则包含一个 virtual 无论如何,主体为空。

对于边缘情况,上述规则有一个例外:如果您的派生类不需要支持多态破坏,那么析构函数不需要是virtual。在这种情况下,改为protected 是正确的; more details here,但请注意,这在实践中很少发生。

【讨论】:

  • 基类析构函数仍在执行。 派生的不是
  • 这是一种奇怪的说法,如果你在基类上调用delete,只会调用基类析构函数(如果不是虚拟的),所以总是调用基类析构函数:-D
  • “将调用错误的析构函数”是不准确的。实际上,只会调用基本的析构函数,并且会调用 UB。
  • @Erik, @Let_Me_Be:为速度而写作是以牺牲正确性为代价的。我一再读就更正了。
  • @Jon:呃,不,不要为了继承而创建析构函数virtual。仅当您打算使用多态性时!否则,您只是无缘无故地强制进行虚拟调度。您确实谈到了这一点,但作为一种罕见的“边缘情况”......并且受保护的析构函数仅对纯虚拟基础有用。亲!
【解决方案2】:

当派生对象被析构并且派生类没有定义析构函数时,是否会自动调用基类析构函数?
是的,无论是否明确定义了派生类析构函数,都会在派生类析构函数之后自动调用基类析构函数。

否则,如果派生类中也有析构函数,是否也需要显式调用基类析构函数?
不,你不需要。 在 C++ 中不会有任何场景,除非使用placement new,否则必须显式调用析构函数。

【讨论】:

    【解决方案3】:

    不,在这种情况下会自动调用基本析构函数,就像可以自动调用基本构造函数一样。

    但请注意,如果您使用多态性并通过基指针进行销毁,则应确保析构函数是虚拟的,否则会中断。

    【讨论】:

      【解决方案4】:

      您应该永远不要从派生类析构函数调用基类析构函数

      原因是基类析构函数将被第二次自动调用,并且以不会导致问题的方式编写析构函数是有问题的 - see this question

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-05
        • 2011-03-11
        • 2014-01-15
        • 1970-01-01
        • 1970-01-01
        • 2013-06-23
        • 2020-09-29
        • 2014-08-08
        相关资源
        最近更新 更多