1

Pretty simple question, how does one handle initializing a class member variable that possibly throws exceptions from it's constructor?

class main
{
public:
    main() c(...) {};
private:
    my_class c;
};

class my_class
{
public:
    inline my_class() : o(...) { };

private:
    some_obj o;
};

Clearly you can't try catch exceptions in a constructor initializer, so then would it be more appropriate instead to construct the object within a try catch block within the constructor?

This is a top-level class, so handling the exception to let a user know what happened and exiting gracefully is a priority over letting the program crash due to the exception?

class main
{
public:
    main()
    {
        try
        {
            c(...);
        }
        catch(...)
        {
            ...
        }
    };
private:
    my_class c;
};

However, this wouldn't work, because the object gets initialized once before it does within the constructor, and therefore the program may crash if the object throws an exception.

Francisco Aguilera
  • 3,099
  • 6
  • 31
  • 57
  • You can use a function-try-block with the constructor, to catch exceptions thrown during initialization of members. Note that the only sensible thing to do here is to re-throw an exception. In most cases it is poor design to allow the program to proceed with a partially-constructed object. – M.M Apr 07 '15 at 01:49
  • @MattMcNabb: A *function-try-block* on a constructor or destructor automatically re-throws at the end of the exception handler. – Remy Lebeau Apr 07 '15 at 04:39
  • @MattMcNabb Yes, I was not intending on continuing the program, rather attempting to perform a more graceful exit. – Francisco Aguilera Apr 07 '15 at 05:59

2 Answers2

2

What you need is function-try-block. It's designed specifically to address your issue.

class main
{
public:
    main() try : c(...)
    {
        std::cout << "constructed, c = " << c << std::endl;
    }
    catch(...)
    {
        std::cerr << "failed to construct c = " << c << std::endl;
    } // implicit throw; here

private:
    my_class c;
};
Francisco Aguilera
  • 3,099
  • 6
  • 31
  • 57
Lingxi
  • 14,579
  • 2
  • 37
  • 93
  • Interesting, never seen this. Is this a c++11+ feature? Are you allowed to use these with constructors? – Francisco Aguilera Apr 07 '15 at 01:47
  • 1
    No. It's a feature C++ has always had. And yes, it can be used with constructors. – Lingxi Apr 07 '15 at 01:48
  • 2
    @FranciscoAguilera this exists *specifically because* a constructor's initializer list allows throw-able code outside of a function body. This is what it's for. – Drew Dormann Apr 07 '15 at 03:42
-1

Why can you not catch the error in the constructor? According to this question it seems to be standard practice.

Community
  • 1
  • 1
Jacob Kern
  • 165
  • 3
  • 12