我一直在做一些阅读,一般意见似乎是尽可能避免两阶段初始化.我同意它所说的大部分内容.但我发现消除它并不容易.
这是一个完全构成的例子,虽然强烈基于一些真实的代码 -
想象一下,我正在构建一个游戏.主游戏类需要构造一个执行3d渲染的"RenderDevice"对象.但是为了构造它,需要从配置文件加载一些设置.并且要绘制一个Window对象.还有一个记录器对象和一个内存池.我的代码现在将所有这些东西作为类成员放在构造函数很少的地方,然后使用相关参数在每个对象上调用init函数,如: -
// Much simplified code to make a point
Game::Game()
{
memoryPool_.init(10000000); // Amount of memory to allocate
logger_.init("logfile.txt", memoryPool_);
window_.init(2000, 1000); // Make a nice big window
renderDevice_.init(window_, logger_, memoryPool_);
}
Run Code Online (Sandbox Code Playgroud)
那对我来说似乎运作得相当好.但这是两个阶段.每个对象仅部分由其构造函数构造.所以我必须做这样的事情而不是让代码"干净".
Game::Game() :
memoryPool_(1000000),
logger_("logfile.txt", memoryPool_),
window_(2000, 1000),
renderDevice_(window_, logger_, memoryPool)
{
}
Run Code Online (Sandbox Code Playgroud)
现在代码看起来对我来说相当丑陋,但也很脆弱,因为初始化的顺序取决于它们在类中声明的顺序,而不是这里列出的顺序.随着越来越多的数据被添加到类中,它变得更糟.这里的对象只需要一些参数,但如果需要更多数据,这将很快失控.
它的优势在于每个对象都可以随时完成它的工作,但它对我来说看起来很丑陋,而且看起来相当脆弱且容易出错......
所以我的问题是我错过了这一点吗?有一个更好的方法吗?我应该停止担心,只是这样做,还是应该使用我的原始代码?或者我的整个设计在某种程度上是错误的,所以问题没有用?
基本上什么是最佳做法?
现在这段代码对我来说似乎很难看
看起来不是那样的.也许你只是不习惯它?
相当脆弱,因为初始化的顺序取决于它们在类中声明的顺序,而不是这里列出的顺序
打开编译器的警告,它应该告诉你这两个命令之间的不匹配.(我知道Clang有这个警告,我很确定GCC也有这个警告.对MSVC不太确定.)
这里的对象只需要一些参数,但如果需要更多数据,这将很快失控.
当你使用时我不明白这有什么不同init().