我目前负责在我们的代码库中查找所有不良做法,并说服我的同事修复有问题的代码.在我的探险过程中,我注意到这里有很多人使用以下模式:
class Foo { public: Foo() { /* Do nothing here */ } bool initialize() { /* Do all the initialization stuff and return true on success. */ } ~Foo() { /* Do all the cleanup */ } };
现在我可能错了,但对我来说这个initialize()方法很糟糕.我相信它取消了拥有构造函数的整个目的.
当我问我的同事为什么做出这个设计决定时,他们总是回答他们别无选择,因为你不能抛弃构造函数而不抛出(我猜他们认为投掷总是很糟糕).
到目前为止,我没有说服他们,我承认我可能缺乏有价值的论据……所以我的问题是:我是否正确,这种结构是一种痛苦,如果是这样,你在其中看到了什么问题?
谢谢.
解决方法
单步(构造函数)初始化和两步(使用init方法)初始化都是有用的模式.我个人认为排除任何一个都是一个错误,虽然如果你的约定完全禁止使用例外,那么你禁止对可能失败的构造函数进行单步初始化.
一般来说,我更喜欢单步初始化,因为这意味着你的对象可以拥有
更强的不变量.当我认为对象能够以“未初始化”状态存在时,我只使用两步初始化.
通过两步初始化,您的对象处于未初始化状态是有效的 – 因此每个与该对象一起工作的方法都需要知道并正确处理事实上它可能处于未初始化的状态.这类似于使用指针,其中假设指针不是NULL是不好的形式.相反,如果您在构造函数中进行了所有初始化并且出现异常,则可以将“对象始终初始化”添加到不变量列表中,因此它变得更容易,更安全对对象的状态做出假设.