两步到一步的初始化和错误处理
Two-step to One-step initialization and error handling
这似乎是一个奇怪的问题。我目前正在将某些对象从两步初始化方案移动到一步初始化方案。基本上将.initialize()
.terminate()
成员函数中的操作转移到构造函数和析构函数中。
我的问题是,重要的是要知道这些类是否正确初始化了某些依赖于外部因素的属性。
一个例子是我的Window类,它创建了一个WinAPI窗口。以前使用两步方法时,我会让initialize()
返回一个布尔值,表示窗口是否正确创建。
if(myWindow.initialize())
{
// proceed with application
}
else
{
// exit
}
是否有任何方法可以在不创建和调用第二个方法(如didMyWindowInitializeCorrectly()
)的情况下从构造函数中继此信息?
起初,我希望有一些类似的东西
if(Window *myWindow = new Window)
{
// proceed with application
}
else
{
// exit
}
但这不会起作用,因为即使窗口创建失败,Window对象仍将实例化。
唯一的解决方案是让构造函数抛出异常,然后捕获它并继续吗?我看了很多线程,人们对C++异常的看法似乎很不一致,所以我不确定什么是最好的方法。
有没有办法用if语句来处理这种情况?
这归结为基于异常或错误代码的初始化的大参数。我通常更喜欢Exceptions来指示构造函数失败,因为当问题没有在稍后的代码中通过is_valid检查或忽略两步返回值来处理时,问题在堆栈跟踪的早期变得更加明显。它还更清楚地说明了初始化失败的原因,而无需查找错误代码。那些喜欢传统的C风格而不是异常风格的失败消息传递的人可能会在最后一点上不同意我的观点。
然而,与代码库的其余部分的风格相匹配通常是个好主意。因此,如果代码中的其他地方没有使用Exceptions,那么最好进行is_valid检查(或原始的两阶段初始化),而不是引入对象验证机制。我更喜欢is_valid,而不是像Riateche发布的两个阶段,因为它让用户能够选择是否/何时检查它是否有效,而无需在合法使用对象之前查找必须调用的函数。
您可以做的一件事是创建一个执行两步初始化的静态方法,即
class Window {
public:
static Window* createWindow() {
Window* w = new Window();
if (w->isValid()) {
return w;
}
delete w;
return NULL;
}
private:
Window();
bool isValid();
};
通过这种方式,您将两步初始化封装为单向初始化。
我当然会使用异常,但如果出于任何原因不需要,您可以覆盖新的运算符,并在出现错误时返回NULL。(只是别忘了释放你的记忆)然后再回来。
void* T::operator new(size_t x);
edit:忘记添加,如果重载new,则需要使用malloc保留内存,并重载delete。
在这种情况下可以使用异常。通常,构造函数必须始终返回有效对象或引发异常。
如果你真的反对例外情况,我建议你使用以下表格:
Window my_window;
if (!my_window.is_valid()) {
cout << "fail";
return;
}
但单独的initialize
方法会更好。
- wxWidgets 拖放文件事件处理程序初始化问题(无效static_cast)
- 当使用lambda进行变量的复杂初始化时,如何处理从内部抛出的lambda外部异常
- 默认情况下初始化时 POD 是否给予特殊处理 (C++14)?
- openGL如何处理发送给它的空/未初始化数据?
- 异常 尝试初始化动态数组时未处理
- C编译器如何使用非初始化的变量处理
- C 正确的方法来初始化和处理映射指针
- 如何编写移动构造函数以处理非初始化的移动
- 处理共享_ptr时非初始化的价值
- 静态变量需要在MAIN处理ARGV参数之前进行初始化
- 初始化静态成员类(用于信号处理程序)
- 如果初始化或销毁因未处理的异常而终止,则必须销毁完全构造的子对象
- 竞争条件:一个线程创建静态对象,另一个线程在初始化完成之前使用它.如何处理
- 两步到一步的初始化和错误处理
- 处理函数初始化的数组
- 编译器能否正确处理静态变量的初始化顺序?
- 每当我尝试初始化Employer对象时,我的程序都会给出一个未处理的异常错误
- 为什么clang和gcc处理结构的支持初始化与类内初始化不同
- TheoraVideoManager不会在0x7329E13D(msvcr110.dll)处初始化未处理的异常
- <Object> 什么是无效初始化(处理<Object>导出)