2017-12-05 11 views
0

私は、Aは抽象クラスとBある階層を持ちC、およびDAの子孫です。私は適切にスマートポインタを使用することができます。このようにC++共有PTRリリース

void doCall() { 

    switch (it) { 
    case 4: 
     theBase = std::make_shared<B>(B(8)); 
     break; 
    case 3: 
     theBase = std::make_shared<C>(C(6)); 
     break; 
    default: 
     theBase = std::make_shared<D>(D(0)); 
     break; 
    } 

    theBase->method(); 

} 

と私は、継承を使用することができます。私はこれを行うdoCall()インサイド

class Controller { 

private: 
int it; 
std::shared_ptr<A> theBase; 

public: 
void doCall(); 
//more code 

} 

:私はAへの共有のポインタを持つクラスController(MVCパターン)を持っていますitの値に従って必要なクラスを取得します。

Controller x; 
x.doCall(); 
x.doCall(); 

私は二回doCall()を呼び出していますので、私は二回switchでつもりです:

は、私はこのコードを呼び出すと仮定します。つまり、std::make_sharedが2回呼び出され、theBaseに割り当てられます。これは安全ですか?

doCall()を初めて呼び出すと、共有ポインタがあります。 2回目に別のstd::shared_ptrtheBaseに割り当てようとしています。古いポインタ(最初の呼び出しの1つ)が破棄され、新しいポインタが作成されますか?それともこのようなことをしなくてはなりませんか?

if (*theBase != nullptr) { 
    theBase.reset(); //delete the old one; 
} 

switch (it) { /* ... */} 

たびdoCall()が呼ばれ、私はtheBaseのサブクラスである新しいオブジェクトを作成する必要があります。私はそれを正しくしていますか?

+3

読んでいる:http://en.cppreference.com/w/cpp/memory/shared_ptr/operator%3D _ "これが既にオブジェクトを所有していて、それを所有する最後のshared_ptrであり、rがそうでない場合*これと同じですが、オブジェクトは所有されているDeleterを通して破棄されます。 "_ –

+0

@RichardCritten reset()を呼び出す必要はないと思うので、2回目にtheBase = std :: make_sharedを呼び出すと、古いポインタは削除され、新しいものが作成されます。メモリリークはなく、我々はすべて満足しています。ありがとうございました! –

答えて

4

何もしないでください。新しく作成したshared_ptrtheBaseに割り当てると、古いカウンタが減分されます。しかし、古いカウンターのカウンターは1です(あなたが他のどこかで参照していないと仮定した場合)。カウンタは0になり、デストラクタが呼び出されます。

次のコードを見てみましょう:

#include <stdio.h> 
#include <memory> 

class myClass 
{ 
public: 
    myClass(int i) : m_i(i) { printf("Constructed %d\n", m_i); } 
    ~myClass() { printf("Destructed %d\n", m_i); } 

    int m_i; 
}; 

int main() 
{ 
    std::shared_ptr<myClass> ptr = std::make_shared<myClass>(5); 

    ptr = std::make_shared<myClass>(10); 
} 

出力は次のようになります。

Constructed 5 
Constructed 10 
Destructed 5 
Destructed 10 

最初のポインタを1秒がより具体的に割り当てられたとき、(作成された直後に破壊され、それはどこです最初のカウンターは減分されます)。

関連する問題