移动和擦除后,对象的容器字段为空

时间:2015-06-14 09:35:37

标签: c++ vector move-semantics erase

我有两个向量,我想将一个对象从一个移动到另一个,在移动它之前,我创建了一个指向该对象的指针。但是当我擦除第一个向量中的索引时,如果我通过指针访问它,则对象中的容器是空的。这很难描述,有些代码会更好地解释它:

Word.h

class Word
{
public:
    Word(string text);
    ~Word();

    string text;
};

Card.h

class Card
{
public: 
    Card(vector<Word>& words);
    ~Card();

    vector<Word> words;
};

main()的

vector<Word> words {
    Word("dog"),
    Word("cat"),
    Word("horse")
};

Card card(words);

vector<Card> deck1;
vector<Card> deck2;

deck1.push_back(move(card));

Card* p = &deck1[0];
deck2.push_back(move(deck1[0]));
cout << p->words.size() << endl; // 3

deck1.erase(deck1.begin());

cout << p->words.size() << endl; // 0 <-- Why is size() 0 here?

p = &deck2[0];
cout << deck2[0].words.size() << endl; // 3 <-- and 3 here
cout << p->words.size() << endl; // <-- and 3 here! 

getchar();

1 个答案:

答案 0 :(得分:2)

移动无效,因为Card没有移动构造函数或移动赋值运算符。向量deck1deck2包含推入其中的任何内容的副本。

但问题(或者至少是一个问题)是当您从p删除时,deck1无效。取消引用p是未定义的行为(UB)。

deck1.push_back(move(card));
Card* p = &deck1[0];
....
deck1.erase(deck1.begin()); // p invalidated
....
cout << p->words.size() << endl; // UB, anything can happen

p = &deck2[0];
cout << deck2[0].words.size() << endl;
cout << p->words.size() << endl; // No problem, p points to deck2[0]