显式调用基类析构函数/构造函数是否合法?

时间:2014-08-29 11:02:00

标签: c++ inheritance constructor destructor

是否合法地构造和构造基类对象以重置基类已知的状态部分?

class C : public BaseClass {...};

C c;
c.BaseClass::~BaseClass();
new (static_cast<BaseClass*>(&c)) BaseClass;

显然,如果我们可以访问类的源代码,还有其他方法可以实现此效果。但是,我想从语言角度了解是否存在无效的具体原因。

2 个答案:

答案 0 :(得分:8)

不,这不合法。您不允许替换对象的基础子对象。

C ++ 11 3.8 / 7指定只能重用对象的存储

  

原始对象是类型为T的最多派生对象(1.8),新对象是类型为T的派生程度最高的对象(也就是说,它们不是基类子对象< /强>)。

您替换的对象是基类子对象,而不是最派生的对象,因此被禁止。

如果您要替换整个对象(即调用~C,然后构建一个新的C),那么这将是合法的,但很危险。如果构造函数抛出,那么该对象将在其生命周期结束时第二次被销毁。这会产生不明确的行为。

答案 1 :(得分:2)

析构函数只有在虚拟的情况下才能工作(否则),否则你会有一个部分被破坏的对象(这似乎是你真正想要的,但是不合法)。新的位置应该有效,但我非常确定标准不是真的允许(尽管我认为它看起来很不错)。而且我不确定为什么你会想要这个,因为对象曾经是派生的C但是在构造之后它再也不会是C,只有BaseClass