在IT技术中,重置基类已知状态的部分,是否可以销毁和重新构建一个基类对象?
class C : public BaseClass {...};
C c;
c.BaseClass::~BaseClass();
new (static_cast<BaseClass*>(&c)) BaseClass;
显然,如果我们可以访问类的源代码,就有其他方法来实现这种效果。但是,从语言角度来看,是否存在特定原因使得这种方法无效,这是我想知道的。
在IT技术中,重置基类已知状态的部分,是否可以销毁和重新构建一个基类对象?
class C : public BaseClass {...};
C c;
c.BaseClass::~BaseClass();
new (static_cast<BaseClass*>(&c)) BaseClass;
显然,如果我们可以访问类的源代码,就有其他方法来实现这种效果。但是,从语言角度来看,是否存在特定原因使得这种方法无效,这是我想知道的。
~C
,然后构造一个新的C
),那么这是合法的,但是很危险。如果构造函数抛出异常,则对象将在其生命周期结束时第二次被销毁。这会产生未定义的行为。C
可能具有指向 BaseClass
分配的资源的指针,这就是 UB 的原因。 - Anton SavinC
,但在构造后它永远不会再是 C
,只会是 BaseClass
。class C
。你在这里做的事情完全是错误的,而且不会起作用。如果 BaseClass
的析构函数是虚拟的,那么 C
的析构函数将被调用,并且对象将被完全销毁,尽管内存不会被释放,因为你没有调用 delete
。如果它不是虚拟的,也许你只会破坏 BaseClass
的位,但我怀疑它能够保证工作。与其这样做,不如在你的 BaseClass
上制作一个简单的 reset()
方法。 - John ZwinckBaseClass::~BaseClass
将防止虚拟分派。 - Simple::
,是我的失误。无论如何,这段代码不能保证按预期工作。 - John Zwinck
ResetBase()
的方法,在基类析构函数中使用它(以避免重复代码),在必要时从派生类中调用它,不要改变析构函数的本意。 - SpookBaseClass
是可分配的,您可以使用static_cast<BaseClass&>(c) = BaseClass();
(或在C++11中,static_cast<BaseClass&>(c) = {};
)来实现相同的效果。 - Casey