Меня смущает состояние объекта после его перемещения с использованием семантики перемещения C++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
, который принимает значениеf2
.- Вызывается конструктор перемещения
Foo
, который перемещает все ресурсы изf1
вf2
. - Теперь вызывается деструктор
f2
, освобождающий все ресурсы. - Теперь вызывается деструктор
f1
, который фактически ничего не делает, так как все ресурсы были переданыf2
. Тем не менее, деструктор вызывается.
Но поскольку вызывается только один деструктор, ни шаг 4, ни шаг 5 не выполняются. Я сделал обратную трассировку от деструктора, чтобы увидеть, откуда он вызывается, и он вызывается с шага 5. Так почему же не вызывается также деструктор f2
?
РЕДАКТИРОВАТЬ: Хорошо, я изменил это, чтобы оно фактически управляло ресурсом. (Внутренний буфер памяти.) Тем не менее, я получаю такое же поведение, когда деструктор вызывается только один раз.
std::move
. Он не сможет вызватьwork
, потому что аргумент фактически является ссылкой lvalue, потому что он был назван. - person jalf   schedule 03.11.2010