Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch a constructor exception?

I have a C++ class which throws an exception from the constructor on failure. How can I allocate a local instance of this class (without using new) and handle any possible exceptions, while keeping the try block scope as small as possible?

Essentially, I am looking for the C++ equivalent of the following Java idiom:

boolean foo() {
    Bar x;
    try {
        x = new Bar();
    } catch (Exception e) {
        return false;
    }
    x.doSomething();
    return true;
}

I do not want to catch exceptions from x.doSomething(), only the constructor.

I suppose what I'm looking for is a way to separate the declaration and the initialization of x.

Is it possible to accomplish this without using heap allocations and pointers?

like image 249
Andrew Sun Avatar asked Aug 02 '16 08:08

Andrew Sun


2 Answers

You can use std::optional from C++17:

bool foo() {
    std::optional<Bar> x; // x contains nothing; no Bar constructed
    try {
        x.emplace();      // construct Bar (via default constructor)
    } catch (const Exception& e) {
        return false;
    }
    x->doSomething();     // call Bar::doSomething() via x (also (*x).doSomething() )
    return true;
}
like image 165
songyuanyao Avatar answered Nov 08 '22 04:11

songyuanyao


This Java idiom doesn't translate well to C++ since Bar x; will require default constructor even if your real constructor requires arguments to be passed.

I'd advise fighting the language to this degree - widening the try block is sufficient - but if you really want to narrow then you could use a function and rely on return value optimisation to obviate a value copy:

Bar foobar()
{
    try {
        return Bar();
    } catch (Exception& e){
        /* Do something here like throwing a specific construction exception
           which you intercept at the call site.*/
    }
}

But really, you could throw a specific exception on construction, so obviating this function approach entirely.

like image 42
Bathsheba Avatar answered Nov 08 '22 02:11

Bathsheba