I've always read that you should never put code in a constructor that might cause an exception. For example if you need to allocate memory in the contructor then put it in an Initialize() method where the exception can be safely caught and/or thrown.
>I've always read that you should never put code
>in a constructor that might cause an exception.
Perhaps you're thinking of destructors and the whole throwing an exception while processing an exception nightmare. The best way to handle a fatal error in the constructor is to throw. Otherwise you're stuck with a partially constructed object, and that way lies madness.
>For example if you need to allocate memory in the contructor then put it in
>an Initialize() method where the exception can be safely caught and/or thrown.
If you're calling the method from the constructor, you've still got the same problem: dealing with a thrown exception within the constructor call chain. Catching an exception can be done in the constructor as well; adding another level of abstraction doesn't change anything if you catch. In fact, it's a good solution (catching and rethrowing) because you have to clean up your mess before throwing a new exception or rethrowing. Destructors aren't called if the constructor throws.
>I had something like this in mind
That defeats the purpose of a constructor. It's also no better than leaving the object in an uninitialized state if the constructor fails, because you have an "initialized--just kidding" object that's in a limbo state until you call a member function. That kind of interface design is painful to use.
>you have to put the whole class in try/catch which might be undesireable or even not possibe
So you'll penalize all users of the class based on a rare or hypothetical test case?
>In the above obj can not be used outside the try block.
Nor should it, if you're using exception handling properly. Also, keep in mind that thrown exceptions unwind the call stack until a catch is found. So if the try block bothers you that much, you can rely on a catch higher up. For example:
Now you're using obj "outside" a try block, but it's still protected by a catch higher up in the call chain. Or you can even ignore the exception altogether and rely on the default behavior of terminating the program.