问题描述
我目前正在与我的老师讨论类设计,我们来到 Initialize()
函数,他大力推广。示例:
class Foo {
public:
Foo()
{//获取只有轻量级资源/默认初始化
}
virtual void Initialize()
{//做分配,获取重量级资源,从磁盘加载数据
}
//可选提供一个Destroy()函数
// virtual void Destroy(){/*...*/}
};
一切都有可选参数。
现在,他还强调类层次结构中的可扩展性和用法(他是一个游戏开发者,他的公司销售一个游戏引擎),其中包含以下参数(逐字逐句,仅翻译):
对构造函数的参数:
- 不能被派生类覆盖
- 不能调用虚函数
的初始化函数Initialize()
/ p>
- 派生类可以完全替换初始化代码
- 派生类可以随时进行基类初始化在其自己的初始化期间
我一直教会在构造函数中直接进行真正的初始化, >提供 Initialize()
函数。也就是说,我肯定没有那么多的经验,因为它涉及到部署库/引擎,所以我想我会问好好的'SO。
那么,这些 Initialize()
函数的参数是什么?它取决于应该使用的环境吗?
strong> Edit :我应该提到,这样的类将仅用作其他类中的成员变量,因为任何其他都不会有意义。对不起,
初始化
在设计良好的代码中,你可能永远不需要它。
反对:非标准,如果使用伪造,可能会破坏构造函数的目的。更重要的是:客户端需要记住调用初始化
。因此,任一实例在构建时将处于不一致的状态,或者它们需要大量的额外记账以防止客户端代码调用任何其他:
void Foo :: im_a_method()
{
if(!fully_initialized)
throw单位化(Foo :: im_a_method在Initialize之前调用);
//做实际工作
}
的代码是开始使用工厂函数。因此,如果您在每个类中都使用初始化
,那么您将需要为每个层次结构都有一个工厂。
词语:不要这样做,如果没有必要;总是检查代码是否可以根据标准结构重新设计。当然不要添加一个 public Destroy
成员,这是析构函数的任务。析构函数可以(在继承的情况下必须) virtual
。
I'm currently having a discussion with my teacher about class design and we came to the point of Initialize()
functions, which he heavily promotes. Example:
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(){ /*...*/ }
};
Everything with optional parameters of course.
Now, he also puts emphasis on extendability and usage in class hierarchies (he's a game developer and his company sells a game engine), with the following arguments (taken verbatim, only translated):
Arguments against constructors:
- can't be overridden by derived classes
- can't call virtual functions
Arguments for Initialize()
functions:
- derived class can completely replace initialization code
- derived class can do the base class initialization at any time during its own initialization
I have always been taught to do the real initialization directly in the constructor and to not provide such Initialize()
functions. That said, I for sure don't have as much experience as he does when it comes to deploying a library / engine, so I thought I'd ask at good ol' SO.
So, what exactly are the arguments for and against such Initialize()
functions? Does it depend on the environment where it should be used? If yes, please provide reasonings for library / engine developers or, if you can, even game developer in general.
Edit: I should have mentioned, that such classes will be used as member variables in other classes only, as anything else wouldn't make sense for them. Sorry.
For Initialize
: exactly what your teacher says, but in well-designed code you'll probably never need it.
Against: non-standard, may defeat the purpose of a constructor if used spuriously. More importantly: client needs to remember to call Initialize
. So, either instances will be in an inconsistent state upon construction, or they need lots of extra bookkeeping to prevent client code from calling anything else:
void Foo::im_a_method()
{
if (!fully_initialized)
throw Unitialized("Foo::im_a_method called before Initialize");
// do actual work
}
The only way to prevent this kind of code is to start using factory functions. So, if you use Initialize
in every class, you'll need a factory for every hierarchy.
In other words: don't do this if it's not necessary; always check if the code can be redesigned in terms of standard constructs. And certainly don't add a public Destroy
member, that's the destructor's task. Destructors can (and in inheritance situations, must) be virtual
anyway.
这篇关于我应该使用虚拟的'Initialize()'函数来初始化我的类的对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!