Constructor finishes by throwing an exception ? Is

2019-01-25 23:25发布

问题:

I was going over this article and it states

Note: if a constructor finishes by throwing an exception, the memory associated with the object itself is cleaned up — there is no memory leak. For example:

void f()
{
X x; // If X::X() throws, the memory for x itself will not leak
Y* p = new Y(); // If Y::Y() throws, the memory for *p itself will not leak
}

I am having difficulty understanding this and would appreciate it if someone could clarify this. I tried the following example which shows that incase of an exception inside a constructor the destructor would not be called.

struct someObject
{
    someObject()
    {
      f = new foo();    
      throw 12;
    }
    ~someObject()
    {
        std::cout << "Destructor of someobject called";
    }

    foo* f;
};

class foo
{
public:
    foo()
    {
            g = new glue();
            someObject a;
    }
    ~foo()
    {
        std::cout << "Destructor of foo";
    }
 private:
  glue* g;
};


int main()
{
    try
    {
        foo a;
    }
    catch(int a)
    {
        //Exception caught. foo destructor not called and someobject destrucotr not called.
       //Memory leak of glue and foo objects
    }
}

How would I fix this issue ?

Sorry for the inconvenience the update might have caused.

回答1:

"... the destructor would not be called."

Since the object isn't considered as constructed yet, after the constructor failed with an exception, the destructor won't be called.

Object allocation, and construction (merely destruction) are different things.

Any objects allocated using new() before the exception is thrown will leak.

You shouldn't manage these resources yourself, unless you're really, really, really need it, and are about 100% sure about what you're doing.

Rather use suitable smart pointers for class members from the standard dynamic memory management library.



回答2:

When the constructor throws, no destructor will be called. When an exception is thrown inside a constructor there are several things that you should take note of in terms of properly handling resource allocations that may have occured in the aborted construction of the object:

  • the destructor for the object being constructed will not be called.
  • destructors for member objects contained in that object's class will be called
  • the memory for the object that was being constructed will be freed.