33

vector.clear()共有ポインタを保持するを呼び出した後、所有するオブジェクトのデストラクタが解放されていないことに気付きましたshared_ptr

コード例を以下に示します。呼び出されてもvector.clear()、共有ポインタの後に呼び出されるデストラクタは範囲を超えています.私の質問は、ベクトル内のすべてのスマートポインタをリセットして手動で削除する必要がありますか? アドバイスできる簡単な方法はありますか?

Output :   

constructor
I am here
destructor

Code:

#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class A
{
public:
    A(){cout << "constructor" << endl;};
    ~A(){cout << "destructor"  << endl;};
};

int main( )
{
    shared_ptr<A> sharedptr (new A);
    std::vector<shared_ptr<A> > test;
    test.push_back(sharedptr);

    test.clear();
    cout << "I am here" << endl;
}
4

4 に答える 4

55

shared_ptr<A>この場合、の 2 つのコピーがあります。1 つはsharedptr変数で、もう 1 つはベクトル内の要素です。

代わりにこれを行う

test.push_back(std::move(sharedptr));

sharedptrオリジナルは内部が移動され、使用できなくなったことに注意してください。もう 1 つのことは、まったく何もしないことです。これは、shared_ptr の完全に有効な使用法でありsharedptr、スコープ外に出た後にそれ自体をクリーンアップします。

于 2013-10-12T13:52:25.470 に答える
10

問題は、 がベクターに のコピーpush_back追加し、メインが存在するまでオリジナルをぶら下げたままにするときに発生します。main スコープに shared_ptr を作成しない場合、問題は発生しません。メイン スコープで shared_ptr を作成することは避けてください。通話中の一時的な権限として設定してください。shared_ptrpush_back

Output is now:   

constructor
I am almost there
destructor
I am here

New code:

#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class A
{
public:
  A(){cout << "constructor" << endl;};
  ~A(){cout << "destructor"  << endl;};
};

int main( )
{
  vector<shared_ptr<A> > test;
  test.push_back(shared_ptr<A>(new A));
  cout << "I am almost there" << endl;
  test.clear();
  cout << "I am here" << endl;
  return 0;
}
于 2013-10-12T16:57:43.643 に答える
4

ここで、 sharedptrとvectorの要素は同じオブジェクトを共有しているため、コンストラクタとデストラクタが 1 回だけ呼び出されます。

于 2014-10-16T13:31:37.860 に答える