Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try catch syntax constructor

Tags:

c++

exception

http://ideone.com/UtVzxw

struct base
{
    base() { throw std::exception(); }
};

struct derived : public base
{
    derived() try : base()  { }

    catch (std::exception& e)
    {
        std::cout << "exception handled" << std::endl;
    }
};

int main()
{
    derived a; // My app crashes.
    return 0;
}

Shoun't my app write "exception handled" and continue running?

The only solution I've found is to surround the construction of "a" in a try/catch block. But If I do that, what's the point of having the try / catch in the constructor at the first place? I'm guessing maybe it's use is to clean up member variables that may have been allocated? since the destructor is not called?

The following works, but handles the exception 2 times.

struct base
{
    base() { throw std::exception(); }
};

struct derived : public base
{
    derived() try : base() { }

    catch(std::exception& e)
    {
      std::cout << "exception 1" << std::endl;
    }
};

int main()
{
    // This works fine.
    try {
       derived a;
    }
    catch(std::exception& e)
    {
      std::cout << "exception 2" << std::endl;
    }
    return 0;
}

I'm just trying to ask myself why I shouldn't simply dodge the try / catch syntax for the constructor and write this:

struct base
{
    base() { throw std::exception(); }
};

struct derived : public base
{
    derived() : base() { }
};

int main()
{
    // This works fine.
    try {
       derived a;
    }
    catch(std::exception& e)
    {
      std::cout << "exception handled" << std::endl;
    }
    return 0;
}
like image 991
Gam Avatar asked Mar 29 '16 00:03

Gam


People also ask

Can we write try catch in constructor?

Like any method can throw exception, a constructor can also throw a exception since it is also a method which is invoked when a object is created. yes we can write a try catch block within a constructor same as we can write in inside a method.

Can we use try catch in constructor C++?

Try/catch blocks should generally be within a function or method, you have it immediately after the public keyword. If you're throwing an exception from the constructor, you don't catch it in the constructor. Instead you catch it in the code that called the constructor ( main in this case).

Can you enclose constructor in try catch block?

No we can not. Constructor is only for initialization of fields.


2 Answers

function-try-block in the constructor doesn't prevent the exception from being thrown. Here's an excerpt from C++ standard draft N4140, [except.handle]:

14 If a return statement appears in a handler of the function-try-block of a constructor, the program is ill-formed.

15 The currently handled exception is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor. Otherwise, ...

The reason for this is that if base class or any member constructor throws an exception, then the construction of the whole object fails, and there's no way to fix it, so the exception has to be thrown.

There's a GOTW on this, and the bottomline is

Constructor function-try-block handlers have only one purpose -- to translate an exception. (And maybe to do logging or some other side effects.) They are not useful for any other purpose.

So, yes, your last code sample is perfectly fine.

like image 127
Anton Savin Avatar answered Oct 28 '22 01:10

Anton Savin


Wrapping a try/catch around a superclass's constructor lets you trap exceptions that get thrown in the superclass's constructor; however the exception gets automatically rethrown when the catch block ends, and the exception continues to propagate.

After all, the superclass did not get constructed. It threw an exception. So you can't really continue on your merry way, in the subclass's constructor, and then end up with a constructed subclass, but with a superclass that did not get constructed. That makes no sense.

From http://en.cppreference.com/w/cpp/language/function-try-block:

The primary purpose of function-try-blocks is to log or modify, and then rethrow the exceptions thrown from the member initializer list in a constructor. They are rarely used with destructors or with regular functions.

This is really the primary value-added of function-try blocks: a convenient place to log "hey, this function threw an exception", that encompasses the entire function, a single place to log this kind of a thing, but without affecting ordinary exception handling.

like image 28
Sam Varshavchik Avatar answered Oct 28 '22 00:10

Sam Varshavchik