Здесь приведен код из Stroustrup "Язык программирования С++", который реализует 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
получает только один раз: когда act1 выходит за рамки. Но из моего понимания: во-первых,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, а также Оптимизация возвращаемого значения, как указано в ответе Билла Линча.