求教一个 c++语法问题, 这段代码为何只析构一次呢

2020 年 11 月 22 日
 jdz
class excption_test
{
public:
excption_test();
~excption_test();
};

excption_test::excption_test()
{
std::cout << "in constructor\n";
}

excption_test::~excption_test()
{
std::cout << "auto in destructor??\n";
}

excption_test get_ex()
{
excption_test c;
return c;
}

int main()
{
excption_test m = get_ex();
return 0;
}

我理解 get_ex()函数中创建了一个对象, 离开栈的时候会进行析构, 析构 c 对象, 同时调用拷贝构造函数拷贝给 main 函数中的 m 变量, 在 main 函数结束的时候再析构 m 对象
2289 次点击
所在节点    程序员
11 条回复
hello2060
2020 年 11 月 22 日
很久没有搞 c++已经想不起来了,你这个 getex()对吗,确定这种写法没啥问题?
hello2060
2020 年 11 月 22 日
我是只直接返回一个栈上对象
hello2060
2020 年 11 月 22 日
如果可以的话看看有编译器优化吗
jdz
2020 年 11 月 22 日
@hello2060 是对的,我测试过。另外不太会看编译器优化,我觉的编译器优化不会改变程序执行结果
codehz
2020 年 11 月 22 日
@jdz RVO 是强制的,NRVO 是可选的,具体内容自己搜索
twoconk
2020 年 11 月 22 日
楼上是正解,实际项目中通常返回堆内存,RVO 即返回值优化,可以少做一次拷贝构造。
zhuangzhuang1988
2020 年 11 月 22 日
这个直接看 <深入理解 C++对象模型>
里面有很多关于 这样的题目
怎么重写
sfqtsh
2020 年 11 月 22 日
See https://en.wikipedia.org/wiki/Copy_elision

g++你可以加选项 -fno-elide-constructors 取消优化
nightwitch
2020 年 11 月 22 日
触发了编译器优化呗,不一定是 RVO,有可能 get_ex()函数整个都被 inline 了,实际上的函数体是
int main(){
excption_test m;
return 0;
}
nightwitch
2020 年 11 月 22 日
在 g++10.2,开最高级别的优化,你的代码实际上被编译成了

int main()
{
std::cout << "in constructor\n";
std::cout << "auto in destructor??\n";
return 0;
}

https://godbolt.org/z/14o3WY
0x11901
2020 年 11 月 24 日
@nightwitch 编译器比我会写代码系列

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.ih06.com/t/728092

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX