由于从构造函数和析构函数内部调用虚拟方法的众所周知的问题,我通常最终得到需要在其构造函数之后调用final-setup方法,并在它们的构造函数之前调用pre-teardown方法的类。析构函数,如下所示:
MyObject * obj = new MyObject;
obj->Initialize(); // virtual method call, required after ctor for (obj) to run properly
[...]
obj->AboutToDelete(); // virtual method call, required before dtor for (obj) to clean up properly
delete obj;
这是可行的,但是却带来了调用者忘记在适当的时间调用这两个方法之一或全部的风险。
所以问题是:C++中有什么方法可以使这些方法自动被调用,因此调用者不必记住要调用它们? (我猜没有,但是我想还是要问一下,以防万一有一些聪明的方法可以做到)
最佳答案
在C++中添加后构造函数的主要问题是,还没有人知道如何处理后构造函数,后构造函数等。
基本理论是对象具有不变性。这个不变量由构造函数建立。一旦建立,就可以调用该类的方法。随着引入需要后构造函数的设计,您将介绍以下情况:一旦构造函数运行,就不会建立类不变式。因此,允许从后构造函数调用虚拟函数同样不安全,并且您将立即失去他们似乎拥有的一项明显好处。
如您的示例所示(可能没有意识到),它们不是必需的:
MyObject * obj = new MyObject;
obj->Initialize(); // virtual method call, required after ctor for (obj) to run properly
obj->AboutToDelete(); // virtual method call, required before dtor for (obj) to clean up properly
delete obj;
让我们说明为什么不需要这些方法。这两个调用可以从
MyObject
或其基数之一调用虚函数。但是,MyObject::MyObject()
也可以安全地调用这些函数。 MyObject::MyObject()
返回后没有任何事情可以使obj->Initialize()
安全。因此,obj->Initialize()
错误或可以将其调用移至MyObject::MyObject()
。同样的逻辑也适用于obj->AboutToDelete()
。派生程度最高的析构函数将首先运行,并且仍然可以调用所有虚拟函数,包括AboutToDelete()
。