两步到一步初始化和错误处理

kbi*_*irk 0 c++ constructor exception-handling initialization

这似乎是一个奇怪的问题.我目前正在将某些对象从两步骤移动到一步式初始化方案.基本上将在.initialize() .terminate()成员函数中完成的操作移动到构造函数和析构函数中.

我的问题是,重要的是要知道这些类是否正确地初始化了某些依赖于外部因素的属性.

一个例子是我的Window类,它创建一个WinAPI窗口.以前使用两步法我会initialize()返回一个是否正确创建窗口的布尔值.

if(myWindow.initialize())
{
    // proceed with application
}
else
{
    // exit
}    
Run Code Online (Sandbox Code Playgroud)

无论如何从构造函数中继这些信息而不创建并且必须调用第二种方法,例如didMyWindowInitializeCorrectly()

起初我希望有一些东西

if(Window *myWindow = new Window)
{
    // proceed with application
}
else
{
    // exit
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为即使窗口创建失败,Window对象仍将实例化.

唯一的解决方案是让构造函数抛出异常然后捕获并继续吗?我看了很多线程,人们对C++异常的看法似乎相当分裂,所以我不确定什么是最好的方法.

无论如何用if语句处理这种情况?

Pyr*_*rce 5

这归结为Exception或基于错误代码的初始化的重要论点.我通常更喜欢Exceptions来指示构造函数失败,因为当代码中的is_valid检查没有处理问题或忽略两步返回值时,问题在堆栈跟踪中变得更加明显.更清楚的是为什么初始化失败而不需要错误代码查找.那些喜欢传统C风格而不是Exception风格失败消息的人可能会在最后一点上不同意我的看法.

但是,匹配代码库其余部分的样式通常是个好主意.因此,如果代码中的其他任何地方都没有使用异常,那么最好在引入对象验证机制时进行is_valid检查(或原始的两阶段初始化).我更喜欢两个阶段的is_valid,就像Riateche发布的一样,因为它让用户能够选择是否/何时想要检查它是否有效,而不需要他们去查找在合法使用对象之前必须调用哪些函数.