2012-01-23 104 views
4

我有一個Foobar類與sayHello()方法輸出「那麼你好!」。如果我寫了下面的代碼移動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]變爲空?爲什麼myFoo2工作?

這裏是Foobar樣子:

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

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

回答

12

不應該fooList [0]成爲空當我做的第一個舉動?

是的。

爲什麼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

答案是:不,移動操作不從容器中刪除元素。

另一種評論:emplace_back函數的使用可能不夠充分。

嘗試:

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

@Mike Seymour澄清move()實際上會將對象移出矢量,但在矢量中將保留一個歸零「unique_ptr」。另外,感謝您指出我的'emplace_back'調用的更改。你的例子編譯並運行良好,我相信它避免了一個額外的構造函數。 –

+0

我編輯了我的原始問題,以反映您的更正情況,以防將來有人在代碼上絆倒。 –

+1

我想突出顯示該項目將持續在矢量內。 –

相關問題