2012-01-23 9 views
4

sayHello()というメソッドを持つFoobarクラスがあり、 "Well hello there!"と出力されます。私は次のコードSTLコンテナから要素を移動すると、そのコンテナから要素が削除されますか?

vector<unique_ptr<Foobar>> fooList; 
fooList.emplace_back(new Foobar()); 

unique_ptr<Foobar> myFoo = move(fooList[0]); 
unique_ptr<Foobar> myFoo2 = move(fooList[0]); 
myFoo->sayHello(); 
myFoo2->sayHello(); 

cout << "vector size: " << fooList.size() << endl; 

を記述する場合、出力は次のようになります。

Well hello there! 
Well hello there! 
vector size: 1 

この作品、なぜ私は混乱しています。最初の移動を行うときにfooList[0]がnullにならないようにする必要がありますか? myFoo2はなぜ機能しますか?私は最初の移動を行うとき

class Foobar 
{ 
public: 
    Foobar(void) {}; 
    virtual ~Foobar(void) {}; 

    void sayHello() const { 
     cout << "Well hello there!" << endl; 
    }; 
}; 

答えて

12

fooList [0]はnullになるべきではない:

はここFoobarは次のようになりますか?

はい。

なぜmyFoo2は機能しますか?

そうではありません。定義されていない動作が発生します。 thisを逆参照しない非仮想関数を呼び出すためにヌルポインタを使用すると、コンパイラはクラッシュしないコードを生成します。

次のように機能を変更した場合、それは何が起こっているのか明確になります。

void sayHello() const { 
    cout << "Well hello there! My address is " << this << endl; 
} 

Well hello there! My address is 0x1790010 
Well hello there! My address is 0 
vector size: 1 
+0

ああ、ほら!それは突然多くの意味があります。ベクトルは依然としてサイズ1と言いますが、今は 'nullptr'へのunique_ptrであり、私が望んでいるようにベクトルが範囲外になったときにクリーンアップされます。あなたが指摘したように私のコンパイラは私のことをちょうどやっているだけです。ありがとう! –

+0

データメンバーを 'Foobar'に追加し、' sayHello() 'にアクセスしました。 'myFoo2'を使用しようとすると、コードがクラッシュします。 –

1

です答え:いいえ、移動操作がコンテナから要素を削除しません。

もう1つのコメント:emplace_back関数の使用は不十分である可能性があります。

試してみてください。

vector<unique_ptr<Foobar>> fooList; 
fooList.emplace_back(new Foobar); 
+1

@Mike Seymourは、move()が実際にオブジェクトをベクトルから移動させますが、ゼロの 'unique_ptr'がベクトルに残ることを明らかにしました。また、私の 'emplace_back'呼び出しの変更を指摘してくれてありがとう。あなたの例はコンパイルされ、正常に実行され、私はそれが追加のコンストラクタを避けると信じています。 –

+0

私は元の質問を編集して、将来の誰かがコードに遭遇した場合の訂正を反映します。 –

+1

私はアイテムがベクトルの中で持続することを強調したいと思いました。 –

関連する問題