Вот код из «Языка программирования C++» Страуструпа, который реализует finally
, который я не могу понять, где вызывается деструктор.
template<typename F> struct Final_action
{
Final_action(F f): clean{f} {}
~Final_action() { clean(); }
F clean;
}
template<class F>
Final_action<F> finally(F f)
{
return Final_action<F>(f);
}
void test(){
int* p=new int{7};
auto act1 = finally( [&]{delete p;cout<<"Goodbye,cruel world\n";} );
}
У меня есть два вопроса по этому поводу:
По словам автора,
delete p
вызывается только один раз: когда акт1 выходит за рамки. Но насколько я понимаю: сначалаact1
будет инициализирован конструктором копирования, затем временный объектFinal_action<F>(f)
в функцииfinally
будет уничтожен, вызываяdelete p
в первый раз, затем второй раз в конце функцииtest
, когдаact1
отсутствует масштаба. Где я ошибаюсь?Зачем нужна функция
finally
? Могу я просто определитьFinal_action act1([&]{delete p;cout<<"Goodbye,cruel world\n"})
? Это то же самое?
Кроме того, если кто-то может придумать лучшее название, пожалуйста, измените текущее.
ОБНОВЛЕНИЕ: после некоторых размышлений я теперь убежден, что деструктор может быть вызван трижды. Дополнительный объект предназначен для временного объекта, автоматически сгенерированного в вызывающей функции void test()
, который используется в качестве аргумента для конструктора копирования act1
. Это можно проверить с помощью опции -fno-elide-constructors
в g++. Для тех, у кого есть тот же вопрос, что и у меня, см. Копировать elision, а также Оптимизация возвращаемого значения, как указано в ответе Билла Линча.
auto
, подумал, что это легче читать. - person Lightness Races in Orbit   schedule 17.09.2015Final_action<???>
из-за лямбда. - person Quentin   schedule 17.09.2015operator=
настроены на удаление, чтобы предотвратить копированиеFinal_action
. Кроме того, в вашем примере кода отсутствует по крайней мере одна точка с запятой послеcout
- person Simon Kraemer   schedule 17.09.2015operator ()
. - person Quentin   schedule 17.09.2015std::function
. - person Quentin   schedule 17.09.2015