I'm having some trouble understanding how Exceptions thrown from constructors work...

Let's say I have a class like this:

class A {
    public:
        A() {
            if( error )
                throw MyExp;
        }
}

If I try to define a variable of type "A" within a try {} catch {} block, I run into problems with scope:

int main() {
    try {
        A a_definition;
    } catch( Exp error ) {
        std::cout << error.message << endl;
    }

    a_definition; // out of scope now...
}

Wrapping the whole program in a try/catch block doesn't seem very appealing to me! And while I could do something like this:

A *a_ptr = NULL;
    try {
        a_ptr = new A;
    } catch( Exp error ) { // so on...

It doesn't look very clean; I don't need a pointer, other than for the work-around.

Is there an easy way to do this?

keep the constructor simple , do some basic initialization which can not fail, move rest of initialization to another function say init

keep the constructor simple , do some basic initialization which can not fail, move rest of initialization to another function say init

Thanks, I can do that.
Just out of curiosity, is there any way to write this with more of a "RAII"-ish behavior, without having to split acquisition and initialization up?

First, there is nothing wrong with this code.

int main() {
    try {
        A a_definition;
    } catch( Exp error ) {
        std::cout << error.message << endl;
    }

    a_definition; // out of scope now...
}

a_definition is indeed out of scope at teh place you mention, but so what ?! You are anyway using it inside the try-catch block (I hope) so you anyway don't it outside the try catch, so let it go out of scope. Now if you really want a code that gives a fake feeling of cleanliness you can do this:

do_that_thing_with_a_definition()
{
    A a_definition;
    //a_definition is in scope.. a neat and clean function...
}
int main() {
    try {
        do_that_thing_with_a_definition() ;
    } catch( Exp error ) {
        std::cout << error.message << endl;
    }

    //following is irrelevant now
    //a_definition; // out of scope now...
}

Your second example is even worse because the object will go out of scope as soon as do_that_thing() returns, so any usage of it inside the try ... catch block will now be illegal.

Back on topic:
If you really need to use code outside the constructor, use pointers, although it is a bad design if you are forced to use an object out of its try catch block.

Your second example is even worse because the object will go out of scope as soon as do_that_thing() returns, so any usage of it inside the try ... catch block will now be illegal.

May be I wasn't clear. What was meant is that create the object and do whatever you wanna do with the object "inside" do_that_thing_with_a_definition(). I thot the name of the function will make it clear. Anyway..

May be I wasn't clear. What was meant is that create the object and do whatever you wanna do with the object "inside" do_that_thing_with_a_definition(). I thot the name of the function will make it clear. Anyway..

Well, except that here:

int main() {
    try {
        do_that_thing_with_a_definition() ;
    } catch( Exp error ) {
        std::cout << error.message << endl;
    }

    //following is irrelevant now
    //a_definition; // out of scope now...

}

You basically implied that a_definition would be in scope out of the try...catch if you used do_that_thing() function. However, that's not the case. It suffers the same fate as the previous problem, so putting it in a function doesn't really do much good. In fact, you've effectively reduced the scope of the object by allocating it in a function.

Problem stmt is: "It doesn't look very clean; I don't need a pointer". So the solution is such that it is "clean" and "doesn't need a pointer".

Problem stmt is: "It doesn't look very clean; I don't need a pointer". So the solution is such that it is "clean" and "doesn't need a pointer".

Clean as it might be, it still doesn't solve the OP's original problem -- which is to be able to use the object outside of the try...catch block.

This article has been dead for over six months. Start a new discussion instead.