I've project which the main look like that
Object a;
if (! a.initialize(x, y, z))
return EXIT_FAILURE;
// 100 lines using a
a.finalize();
I trying to change this part of code and using RAII idiome.
So, I delete initialize
function and finalize
and move the code in the constructor and destructor.
In order to catch initialize()
error, I throw an exception in the constructor if something fail.
So now, my code goes like this :
try
{
Object a(x, y, z);
// 100 lines using a
} catch (my_exception&)
{
return EXIT_FAILURE;
}
the think that bother is the 100 lines of code. My try
is too long for just one error. And I've multiple object like a
.
so before my code was linear :
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();
Now it looks ugly, difficult to read :
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;
}
How to do to use RAII and keep a code clear ?
In general, create a try block at the level at which you want to handle the exception. In this case, you just need a top-level block to clean up after any exception:
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;
}
Now it's not "too long for one error"; it's the right length for any error which might occur.
It would be a good idea to restrict yourself to exceptions derived from std::exception
; then you could give some potentially useful information in the case that it's not handled:
catch (std::exception const & ex) {
std::cerr << "ERROR: " << ex.what() << std::endl;
return EXIT_FAILURE;
}