Why is the destructor not invoked in this code?
#include <boost/scoped_ptr.hpp>
#include <iostream>
class MyClass {
boost::scoped_ptr<int> ptr;
public:
MyClass() : ptr(new int) { *ptr = 0; throw; std::cout<<"MyClass Allocated\n"; }
~MyClass() { std::cout<<"MyClass De-allocated\n"; }
int increment() { return ++*ptr; }
};
int main()
{
boost::scoped_ptr<MyClass> myinst(new MyClass);
std::cout << myinst->increment() << '\n';
std::cout << myinst->increment() << '\n';
}
EDIT
From the answers, In understand that when an exception happens in the constructor, destructor will not be invoked. But if the exception happens in the main(), ie after the MyClass object is fully instantiated, will the MyClass destructor be invoked? If not, then why it is a smart pointer?
Adding the code
#include <boost/scoped_ptr.hpp>
#include <iostream>
class MyClass {
boost::scoped_ptr<int> ptr;
public:
MyClass() : ptr(new int) { *ptr = 0; std::cout<<"MyClass Allocated\n"; }
~MyClass() { std::cout<<"MyClass De-allocated\n"; }
int increment() { return ++*ptr; }
};
int main()
{
boost::scoped_ptr<MyClass> myinst(new MyClass);
throw 3;
std::cout << myinst->increment() << '\n';
std::cout << myinst->increment() << '\n';
}
Output:
MyClass Allocated
terminate called after throwing an instance of 'int'
Aborted
A C++ object’s lifetime begins only after its constructor completes successfully.
Since the exception was thrown before constructor call was complete you don’t have an complete object and hence no destructor.
Herb Sutter explains this nicely, to quote him:
EDIT 1:
But if the exception happens in the
main(), ie after theMyClassobject is fully instantiated, will theMyClassdestructor be invoked?Yes, it will be!
That is the purpose of using
scoped_ptr, Once an exception is thrown inmain, Stack Unwinding would cause all local objects to be deallocated, this means thatmyinst(which resides on stack) will also be deallocated, which in turn will call the destructor ofMyClass.Refer the Boost doccumentation when in doubt:
EDIT 2:
Why does your edited program crash?
Your program shows crashes because, You throw an exception but you never catch it. when such a scenario occurs an special function called
terminate()is called whose default behavior is to callabort().It is implementation defined behavior whether stack is Unwound beforeterminate()is called in this particular scenarioRef 1.Seems your implementation doesn’t & you should not rely on this behavior as well.You can modify your program as follows to handle the exception and you should get the behavior you were expecting:
Ref1C++03 15.5.1 The terminate() function