Epi*_*lle 1 c++ exception raii
我的项目主要看起来像那样
Object a;
if (! a.initialize(x, y, z))
return EXIT_FAILURE;
// 100 lines using a
a.finalize();
Run Code Online (Sandbox Code Playgroud)
我试图改变这部分代码并使用RAII idiome.所以,我删除了initialize函数,finalize并在构造函数和析构函数中移动代码.
为了捕获initialize()错误,如果出现故障,我会在构造函数中抛出异常.
所以现在,我的代码是这样的:
try
{
Object a(x, y, z);
// 100 lines using a
} catch (my_exception&)
{
return EXIT_FAILURE;
}
Run Code Online (Sandbox Code Playgroud)
认为麻烦的是100行代码.我try只是一个错误太长了.而且我有多个对象a.
所以在我的代码是线性之前:
Object a;
if (! a.initialize(x, y, z))
return EXIT_FAILURE;
Object b;
Object c;
if (!b.initialize() || !c.initialize())
return EXIT_FAILURE;
a.finalize();
Run Code Online (Sandbox Code Playgroud)
现在它看起来很难看,难以阅读:
try
{
Object a(x, y, z);
try
{
Object b;
try
{
Object c;
}
catch (my_exception_c&)
{
return EXIT_FAILURE;
}
}
catch (my_exception_b&)
{
return EXIT_FAILURE;
}
} catch (my_exception&)
{
return EXIT_FAILURE;
}
Run Code Online (Sandbox Code Playgroud)
如何使用RAII并保持代码清晰?
通常,在要处理异常的级别创建一个try块.在这种情况下,您只需要一个顶级块来清除任何异常后:
try {
Object a(x, y, z);
Object b;
Object c;
// code using these
} catch (...) {
// end the program if any exception hasn't been handled
return EXIT_FAILURE;
}
Run Code Online (Sandbox Code Playgroud)
现在它不是"一个错误太长"; 对于可能发生的任何错误,它是正确的长度.
将自己局限于源自的异常是一个好主意std::exception; 那么你可以在没有处理的情况下给出一些可能有用的信息:
catch (std::exception const & ex) {
std::cerr << "ERROR: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
Run Code Online (Sandbox Code Playgroud)