gpt4 book ai didi

c++ - 如何为从 C++ 中的函数返回的临时对象调用析构函数?

转载 作者:IT老高 更新时间:2023-10-28 22:19:52 26 4
gpt4 key购买 nike

这是来自 Stroustrup 的“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";} );
}

我有两个问题:

  1. 据作者所说,delete p只被调用一次:当 act1 超出范围时。但据我了解:首先,act1将使用复制构造函数初始化,然后是临时对象 Final_action<F>(f)在函数 finally被破坏,调用 delete p第一次,然后在函数结束时第二次 testact1超出范围。我哪里弄错了?

  2. 为什么是 finally需要的功能?我不能只定义Final_action act1([&]{delete p;cout<<"Goodbye,cruel world\n"})吗? ?是一样的吗?

另外,如果有人能想到更好的标题,请修改当前标题。

更新:经过进一步思考,我现在确信析构函数可能会被调用三次。额外的一个用于调用函数中自动生成的临时对象 void test()用作 act1 的复制构造函数的参数.这可以通过 -fno-elide-constructors 进行验证g++ 中的选项。和我有同样问题的 friend ,请看Copy elision以及 Return value optimization正如比尔林奇的回答所指出的那样。

最佳答案

您是对的,此代码已损坏。只有在 return value optimizations 时才能正常工作被应用。这一行:

auto act1 = finally([&]{delete p;cout<<"Goodbye,cruel world\n"})

可能会或可能不会调用复制构造函数。如果是这样,那么您将拥有两个 Final_action 类型的对象,因此您将调用该 lambda 两次。

关于c++ - 如何为从 C++ 中的函数返回的临时对象调用析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32632569/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com