Code snippet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#include <iostream> #include <boost/shared_ptr.hpp> class A { public: A() { std::cout << "in A::A()." << std::endl; } ~A() { std::cout << "in A::~A()." << std::endl; } }; class B { public: B() { std::cout << "in B::B()." << std::endl; throw 1024; } ~B() { std::cout << "in B::~B()." << std::endl; } }; class C { public: C() : m_a(new A), m_b(new B) { } #ifndef _USE_SHARED_PTR ~C() { delete m_b; delete m_a; } #endif private: #ifndef _USE_SHARED_PTR A *m_a; B *m_b; #else boost::shared_ptr<A> m_a; boost::shared_ptr<B> m_b; #endif }; int main() { try { C c; } catch (...) { } return 0; } |
Output:
1 2 3 4 5 6 7 8 9 |
binson@binson-precise:~$ g++ ptr.cpp -o ptr binson@binson-precise:~$ ./ptr in A::A(). in B::B(). binson@binson-precise:~$ g++ -D_USE_SHARED_PTR ptr.cpp -o ptr binson@binson-precise:~$ ./ptr in A::A(). in B::B(). in A::~A(). |
Exception safety is ensured, when using shared_ptr
. Memory allocated by m_a is freed even when an exception is thrown. The trick is: the destructor of class shared_ptr
is invoked after the destructor of class C
.