2012-01-23 2 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, но теперь это просто unique_ptr для 'nullptr' и будет очищен, когда вектор выходит из области видимости, как я надеюсь. Похоже, все работает так, как я ожидал, мой компилятор, как вы указали, просто играет на меня. Благодаря! –

+0

Я добавил член данных к 'Foobar' и получил доступ к нему в' sayHello() '. Теперь код падает, как и ожидалось при попытке использовать 'myFoo2'. –

1

Ответ: Нет, перемещение операции не удаляет элементы из контейнера.

Другой комментарий: использование функции emplace_back, вероятно, будет неадекватным.

попробовать:

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

@ Майк Сеймур пояснил, что move() фактически перенесет объект из вектора, но обнуленный 'unique_ptr' останется в векторе. Кроме того, спасибо, указав изменение для моего вызова 'emplace_back'. Ваш пример компилируется и работает нормально, я считаю, что он избегает дополнительного конструктора. –

+0

Я отредактировал свой оригинальный вопрос, чтобы отразить вашу коррекцию, если кто-то в будущем наткнется на код. –

+1

Я хотел бы выделить элемент, который будет сохраняться внутри вектора. –

Смежные вопросы