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

2020-11-22 18:06:20 +08:00
 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 对象
1646 次点击
所在节点    程序员
11 条回复
hello2060
2020-11-22 18:16:08 +08:00
很久没有搞 c++已经想不起来了,你这个 getex()对吗,确定这种写法没啥问题?
hello2060
2020-11-22 18:16:47 +08:00
我是只直接返回一个栈上对象
hello2060
2020-11-22 18:19:56 +08:00
如果可以的话看看有编译器优化吗
jdz
2020-11-22 18:26:31 +08:00
@hello2060 是对的,我测试过。另外不太会看编译器优化,我觉的编译器优化不会改变程序执行结果
codehz
2020-11-22 18:36:05 +08:00
@jdz RVO 是强制的,NRVO 是可选的,具体内容自己搜索
twoconk
2020-11-22 18:44:37 +08:00
楼上是正解,实际项目中通常返回堆内存,RVO 即返回值优化,可以少做一次拷贝构造。
zhuangzhuang1988
2020-11-22 18:54:50 +08:00
这个直接看 <深入理解 C++对象模型>
里面有很多关于 这样的题目
怎么重写
sfqtsh
2020-11-22 19:23:57 +08:00
See https://en.wikipedia.org/wiki/Copy_elision

g++你可以加选项 -fno-elide-constructors 取消优化
nightwitch
2020-11-22 19:36:26 +08:00
触发了编译器优化呗,不一定是 RVO,有可能 get_ex()函数整个都被 inline 了,实际上的函数体是
int main(){
excption_test m;
return 0;
}
nightwitch
2020-11-22 19:44:55 +08:00
在 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 16:17:28 +08:00
@nightwitch 编译器比我会写代码系列

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

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

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

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

© 2021 V2EX