C ++可以使析构函数不调用类成员的析构函数和基类的析构函数?

时间:2017-05-30 11:30:39

标签: c++

有没有办法让类的析构函数不调用其中一个类成员的析构函数和/或NOT调用其基类的析构函数?

如果无法做到这一点,是否正在创建某些具有placement-new的类成员并手动破坏(/ not-destructing)它们可能的解决方法?谢谢!

编辑: 我需要这个的原因:C类拥有对象M.M有一个非平凡的析构函数。 C是M的朋友,并且管理M的方式是不需要调用M的析构函数。可以调用它,但这意味着性能开销。 (在这种情况下,这是一个问题。) 我想从M创建一个派生类,它有一个什么都不做的析构函数,但那时它仍然会调用基础的析构函数。

2 个答案:

答案 0 :(得分:3)

在构造时,C ++确保首先调用子类构造函数,然后构造成员,最后应用适当的构造函数。在破坏时,对称完成。

这意味着一旦对象被破坏,你就无法阻止基类析构函数的应用,也不能阻止任何成员构造函数的应用。如果你只想破坏一些,你必须找到一种不破坏对象的方法(只需使用原始指针......)并手动调用你想要的析构函数。但你肯定不想这样做!

C ++对程序员技能非常有信心,因此编写一个调用未定义行为的程序很容易。如果您发现自己试图颠覆C ++编译器而不调用基类或成员的析构函数,则会遇到一个主要问题。您不想销毁的成员不应该是成员,更可能是指针(原始或共享)或对具有自己的生命周期管理的外部对象的引用。并且基类也可能是指向外部对象的指针或引用,这里生命周期可以(并且应该)在类之外进行管理。

答案 1 :(得分:1)

如果析构函数具有可观察的副作用,那么在不调用析构函数的情况下结束对象的生命周期将是未定义的行为。这包含在C ++ 14 [basic.life] / 4:

  

程序可以通过重用对象占用的存储或通过使用非平凡的析构函数显式调用类类型的对象的析构函数来结束任何对象的生命周期。对于具有非平凡析构函数的类类型的对象,程序不需要在重用或释放对象占用的存储之前显式调用析构函数;但是,如果没有对析构函数的显式调用或者如果没有使用delete-expression来释放存储,则不应该隐式调用析构函数,并且任何依赖于析构函数产生的副作用的程序都有未定义的行为。 / p>

所以,没有办法解决它。也许您可以重新设计代码,以便析构函数不会执行任何不必要的语句或其他内容。