Здесь приведен код из 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, а также Оптимизация возвращаемого значения, как указано в ответе Билла Линча.