What will happen if caught exception when new a object? For example:

ClassTest* ptr = 0;
  try
  {
      ptr = new ClassTest;
   }
   catch(...)
   {
   }

if the constructor of ClassTest throw exception, what will happen?
will ptr == 0 ?
some memory leak?

>if the constructor of ClassTest throw exception, what will happen?
Why don't you try it and see?

>will ptr == 0 ?
That's a good assumption.

>some memory leak?
It depends on what throws the exception and how you deal with it. If your constructor allocates memory but doesn't release it when the exception is thrown, you have a memory leak.

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 did not mean to call Initialize() from the constructure because that wouldn't help at all. I had something like this in mind:

class foo
{
public:
    foo() {ptr = 0;}
    void Initialize()
    {
          try
          {
               ptr = new char[255];
          }
          catch(...)
          {
               throw;
           }
    }
   
private:
    char* ptr;
};

int main()
{
     foo obj;
     try
     {
             obj.Initialize();
     }
     catch(...)
     {
          cout << "bad obj\n";
     }
}

If you allow try/catch in the constructor then you have to put the whole class in try/catch which might be undesireable or even not possible

int main()
{
    try
    {
         foo obj;
    }
}

In the above obj can not be used outside the try block.

>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:

void blah()
{
  foo obj;
}

int main() try
{
  blah();
}
catch ( ... ) {
  // Handle errors
}

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.

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