2016-06-21 11 views
4

std::unique_ptrの助けを借りて安全なコピーコンストラクタを書くことが可能かどうかを調べようとしています。
これは私のコードです:スマートポインタを使って安全なコピーコンストラクタを書く

#include <iostream> 
#include <memory> 

class A { 
public: 
    A():_a(10){ 
    std::cerr << "A() constructor" << std::endl; 
    } 

    A(const A& tmp){ 
    _a = tmp._a; 
    std::cerr << "A() copy constructor" << std::endl; 
    } 

    ~A(){ 
    std::cerr << "~A()" << std::endl; 
    } 

    int _a; 
}; 

class B { 
public: 
    B():_b(5){ 
    std::cerr << "B() constructor" << std::endl; 
    } 

    B(const B& tmp){ 
    std::cerr << "B() copy constructor" << std::endl; 
    throw std::exception("exc"); 
    } 

    ~B(){ 
    std::cerr << "~B()" << std::endl; 
    } 

    int _b; 
}; 

class C { 
public: 
    C():a(nullptr),b(nullptr){ 
    std::cerr << "C() constructor" << std::endl; 
    } 
    C(const C& tmp){ 
    std::cerr << "C() copy constructor" << std::endl; 

    std::unique_ptr<A> _a(new A(*tmp.a)); 
    std::unique_ptr<B> _b(new B(*tmp.b)); 

    a = _a.release(); 
    b = _b.release(); 
    } 
    ~C(){ 
    std::cerr << "~B()" << std::endl; 
    } 

    A* a; 
    B* b; 
}; 

int main(int argc, char** argv){ 
    A a; 
    B b; 
    C c; 
    c.a = &a; 
    c.b = &b; 
    C c2(c); 
    return 0; 
} 

そして、このコードの出力:

A() constructor 
B() constructor 
C() constructor 
C() copy constructor 
A() copy constructor 
B() copy constructor 

だから、質問はなぜデストラクタが呼び出されていませんか?
私は、std::unique_ptr<A> _aが範囲外になり、オブジェクトを破棄しなければならないと考えています。

+0

、 'unique_ptr'が選択 – sp2danny

+1

のごsmartpointerない'だから、質問はなぜデストラクタは呼ばれないんですか? 'あなたが' B'のコピーコンストラクタを投げたからです。 – 101010

+0

@ 101010これでも '_a'のdtorが起動すると予想されます。 – Angew

答えて

9

スタックの巻き戻しは、例外が常にキャッチされた場合にのみ保証されます。 try-catchブロックをmainに追加すると、デストラクタが正しく呼び出されることがわかります。あなたはコピーコンストラクタが必要な場合は

[Live example]

関連する問題