Xeo*_*Xeo 16 c++ initialization
我正在和我的老师讨论关于课堂设计的问题,我们谈到了Initialize()
他大力宣传的职能.例:
class Foo{
public:
Foo()
{ // acquire light-weight resources only / default initialize
}
virtual void Initialize()
{ // do allocation, acquire heavy-weight resources, load data from disk
}
// optionally provide a Destroy() function
// virtual void Destroy(){ /*...*/ }
};
Run Code Online (Sandbox Code Playgroud)
当然,一切都有可选参数.
现在,他还强调了类层次结构中的可扩展性和使用(他是一个游戏开发者,他的公司出售游戏引擎),并带有以下参数(逐字逐句,仅翻译):
反对构造函数的论据:
Initialize()
功能参数:
我一直被教导直接在构造函数中进行实际初始化,并且不提供这样的Initialize()
函数.也就是说,我肯定没有他在部署库/引擎时那么多的经验,所以我想我会问好吧.
那么,支持和反对这些Initialize()
功能的论点到底是什么?它是否取决于应该使用的环境?如果是,请为图书馆/引擎开发人员提供推理,如果可以的话,请为游戏开发人员提供一般推理.
编辑:我应该提到,这些类将仅用作其他类中的成员变量,因为其他任何东西对它们都没有意义.抱歉.
对于Initialize
:老师说的正是如此,但在精心设计的代码中,您可能永远不需要它.
反对:非标准,如果虚假使用可能会破坏构造函数的目的.更重要的是:客户需要记得打电话Initialize
.因此,任何一个实例在构建时都会处于不一致状态,或者它们需要大量额外的簿记来防止客户端代码调用其他任何内容:
void Foo::im_a_method()
{
if (!fully_initialized)
throw Unitialized("Foo::im_a_method called before Initialize");
// do actual work
}
Run Code Online (Sandbox Code Playgroud)
防止这种代码的唯一方法是开始使用工厂函数.因此,如果您Initialize
在每个类中使用,则每个层次结构都需要一个工厂.
换句话说:如果没有必要,不要这样做; 始终检查代码是否可以根据标准结构重新设计.当然不添加public Destroy
成员,这是析构函数的任务.virtual
无论如何,析构函数都可以(并且在继承情况下).
我反对C++中的'双初始化'.
反对构造函数的论据:
- 不能被派生类覆盖
- 无法调用虚函数
如果你必须编写这样的代码,这意味着你的设计是错误的(例如MFC).设计您的基类,以便可以覆盖的所有必要信息通过其构造函数的参数传递,因此派生类可以像这样覆盖它:
Derived::Derived() : Base(GetSomeParameter())
{
}
Run Code Online (Sandbox Code Playgroud)
这是一个可怕的,可怕的想法.问问自己 - 如果你Initialize()
以后必须打电话,构造函数有什么意义?如果派生类想要覆盖基类,则不要派生.
当构造函数完成时,使用该对象应该是有意义的.如果没有,你做错了.
归档时间: |
|
查看次数: |
3934 次 |
最近记录: |