Я запутался в состоянии объекта после его перемещения с использованием семантики перемещения С++ 0x. Я понимаю, что после перемещения объекта он все еще является действительным объектом, но его внутреннее состояние было изменено так, что когда его деструктор вызывается, ресурсы не освобождаются.
Но если мое понимание правильное, деструктор перемещаемого объекта все равно должен быть вызван.
Но этого не происходит, когда я выполняю простой тест:
struct Foo
{
Foo()
{
s = new char[100];
cout << "Constructor called!" << endl;
}
Foo(Foo&& f)
{
s = f.s;
f.s = 0;
}
~Foo()
{
cout << "Destructor called!" << endl;
delete[] s; // okay if s is NULL
}
void dosomething() { cout << "Doing something..." << endl; }
char* s;
};
void work(Foo&& f2)
{
f2.dosomething();
}
int main()
{
Foo f1;
work(std::move(f1));
}
Этот вывод:
Constructor called!
Doing something...
Destructor called!
Обратите внимание, что деструктор вызывается только один раз. Это показывает, что мое понимание здесь не работает. Почему деструктор не назывался дважды? Здесь моя интерпретация того, что должно было произойти:
-
Foo f1
. -
Foo f1
передаетсяwork
, который принимает значение rf2
. - Конструктор перемещения
Foo
равен вызванный, перемещая все ресурсы вf1
доf2
. - Теперь вызывается деструктор
f2
, освобождая все ресурсы. - Теперь вызывается деструктор
f1
, который на самом деле ничего не делает поскольку все ресурсы были переданы доf2
. Тем не менее, деструктор но тем не менее.
Но так как вызывается только один деструктор, ни шаг 4, ни шаг 5 не происходит. Я сделал backtrace от деструктора, чтобы увидеть, откуда он вызывается, и он вызывается с шага 5. Так почему же не вызывается деструктор f2
?
EDIT: Хорошо, я изменил это так, чтобы он фактически управлял ресурсом. (Внутренний буфер памяти.) Тем не менее, я получаю такое же поведение, когда деструктор вызывается только один раз.