为什么返回值优化需要显示的提供一个子copy constructor,,,但是又不调用它呢?

R9R9R9 2006-09-09 11:38:41
class RVO
{
public:

RVO(){printf("I am in constructor\n");}
RVO (const RVO& c_RVO) {printf ("I am in copy constructor\n");}
~RVO(){printf ("I am in destructor\n");}
int mem_var;
};
RVO MyMethod (int i)
{
RVO rvo;
rvo.mem_var = i;
return (rvo);
}
int main()
{
RVO rvo;
rvo=MyMethod(5);
}

若启用 NRVO (cl /O2 sample1.cpp),预期输出将是:

I am in constructor
I am in constructor
//并不调用copy constructor
I am in destructor
I am in destructor

以上只是网上看到的,,,尚没有验证过,,,因为偶不知道如何打开VC 。NET 2003里的优化设置,
我把全部的优化都打开了,为何还是跟没有优化过的一样呢?不知道哪里出错了,步骤是这样的吗?

项目属性--->C/C++-->优化....

本人比较菜点,,,大家说的详细一下啊。。。谢谢哈哈
...全文
185 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
过客猫2022 2006-09-10
  • 打赏
  • 举报
回复
RVO rvo; //调用默认构造函数
RVO r(rvo); //调用copy构造涵数
或RVO r=rvo;也是调用copy构造函数
如果你没有定义copy构造函数,系统会默认产生一个按位copy的构造函数
相当于:memcpy((void*)&r,(void*)rvo,sizeof(RVO));
也可以禁用,你将其定义为private的就可以了!

OOPhaisky 2006-09-10
  • 打赏
  • 举报
回复
哎呀,第一句说错了,更正:

返回值优化的主要目的就是为了消除由于调用copy constructor而导致的开销。......
OOPhaisky 2006-09-10
  • 打赏
  • 举报
回复
为什么返回值优化需要显示的提供一个子copy constructor,,,但是又不调用它呢?
----------------------------------------------------------------------------
返回值的主要目的就是为了消除由于调用copy constructor而导致的开销。如果你没有显示提供copy constructor,那么编译器就会为你自动合成一个,但是编译器很可能会认为自己合成的这个copy constructor是trivial的(也就是几乎什么都不做),也就是说调用这个自己合成的copy constructor并没有什么额外的性能开销,所以此时编译器不会执行返回值优化。但是如果你显示提供了一个copy construtor,那么编译器就认为这个copy constructor肯定会做一些实际的事情(可能实际上你也没做什么),进而会导致一定的开销,所以它会打开返回值优化的功能,将临时对象优化掉。
所以,你可以把“自己定义copy constructor”当成打开编译器返回值优化功能的“开关”。
cunsh 2006-09-10
  • 打赏
  • 举报
回复
为什么返回值优化需要显示的提供一个子copy constructor,,,但是又不调用它呢?
==================

不知道说的什么意思. 这个优化就是所有return都返回同一个对象的话就直接把对象构造在返回的对象那里.所以少了拷贝构造函数.但这种行为可能并不是作者想要的.比较麻烦.
cunsh 2006-09-10
  • 打赏
  • 举报
回复

devc++编译的看上去用了这个优化
jixingzhong 2006-09-10
  • 打赏
  • 举报
回复
调用被优化,
那是环境的事情,
你可以尝试关闭优化选项看看结果 ...
jixingzhong 2006-09-10
  • 打赏
  • 举报
回复
返回的时候,
返回对象先被拷贝到一个临时对象中,
然后从临时对象拷贝到接收对象中 ...

所以拷贝构造是需要的。
jixingzhong 2006-09-10
  • 打赏
  • 举报
回复
return (rvo);

这里返回的时候需要一个临时对象,
从这个 rvo 到临时对象就需要这个 拷贝构造 ....
光明山人 2006-09-10
  • 打赏
  • 举报
回复
rvo=MyMethod(5); 调用的是 operator= 而不是 copy constructor 。你可以定义一个 operator= 验证一下。

要想使用 copy constructor ,应该这样:
RVO rvo(MyMethod(5));
SammyLan 2006-09-10
  • 打赏
  • 举报
回复
NRV优化在Inside the C++ Object Model里面有讲到
不过好像VS是无论你提供不提供拷贝构造函数,他都照样优化

印象中NRV优化不是你这样用的
NRV优化是用在初始化表达式中的,如
RVO rvo=MyMethod(5);
在这里本身MyMethod(5)返回的时候都要调用拷贝构造函数,然后初始化rvo的时候又要调用一次拷贝构造函数,理论上应该调用两次拷贝构造函数的.但是应用了NRV之后只调用了一次拷贝构造函数 (=_=)
一家之见,各为继续.....
guo0084 2006-09-10
  • 打赏
  • 举报
回复
你可以把“自己定义copy constructor”当成打开编译器返回值优化功能的“开关”。
--------------------------------------------------------------------------------
我在lippman的书上也看到过。vs是不支持这种NRV优化的,所以楼主得到的结果是正常的。
我用dev-c++测试到的结果是这样的。
I am in constructor
I am in constructor
I am in destructor

这个结果也可以理解,因为经过NRV优化之后,大概是这样的。
但是有一点比较奇怪,我在dev-c++上把copy constructor注释掉,也会得到同样的结果,而且优化之后更本就没有调用copy constructor函数。为什么lippman会说copy constructor是开关????

void MyMethod (RVO& rvo, int i)
{
rvo.RVO::PVO();
rvo.mem_var = i;
}
int main()
{
RVO rvo;
rvo.RVO::RVO();
rvo=MyMethod(5);
rvo.RVO::~RVO();
}
OOPhaisky 2006-09-10
  • 打赏
  • 举报
回复
^_^
R9R9R9 2006-09-10
  • 打赏
  • 举报
回复
to: OOPhaisky(异化$渴望成功~~)

看来又是编译器在搞鬼哦。。。呵呵,再放一天,看看有没有其他不同意见的,没有的话就给分了。呵呵

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧