求助,为什么这种情况下没有产生临时变量?

竹剑单 2020-03-27 12:33:44

class yc {
public:
yc() {
cout << "yc construct" << endl;
}
yc(yc&& y) {
cout << "move construct &&" << endl;
}
yc(const yc& y) {
cout << "copy construct&" << endl;
}
yc& operator =(const yc& yy) {
cout << " = constructor" << endl;
return *this;
}
~yc() {
cout << "deconstrutor" << endl;
}
};

yc getY() {
shared_ptr<yc> y(new yc());
return *y;
}

int main(){

yc t(getY());

return 0;
}

输出:
yc construct
copy construct&
deconstrutor
deconstrutor

第一个constructor是getY中构造对象的,
copy constructor是main函数中的拷贝构造,
我的问题是getY()不会生成一个临时变量吗?如果有临时变量的话中间应该还有一步copy constructor才对啊?求助

运行环境:VS2015,禁用了所有优化
...全文
225 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
竹剑单 2020-03-27
  • 打赏
  • 举报
回复
感谢各位的回答,虽然我还是不太懂,慢慢学习
qybao 2020-03-27
  • 打赏
  • 举报
回复
shared_ptr<yc> y(new yc()); 相当于 yc *y1 = new yc(); //这里调用构造函数 shared_ptr<yc> y(y1); //这里用智能指针引用y1,也就是y直接引用y1,不会发生拷贝 getY返回*y就是返回y指向的对象,本来是个临时对象,但是t(getY())的t调用的构造函数需要的是引用的参数,也就是getY返回的临时对象直接被引用当作参数传给了t,所以发生拷贝的是t,y本身没有发生拷贝
真相重于对错 2020-03-27
  • 打赏
  • 举报
回复
coo135 2020-03-27
  • 打赏
  • 举报
回复
C++标准规定,在对象的初始化中,当源对象是无名临时量对象时,就会进行复制消除(省略复制构造函数)。 比如:yc t(yc()); 什么都不会输出。
竹剑单 2020-03-27
  • 打赏
  • 举报
回复
引用 16 楼 coo135 的回复:
[quote=引用 14 楼 pokuwa 的回复:] [quote=引用 13 楼 pokuwa 的回复:] [quote=引用 12 楼 coo135 的回复:] 补充一次,原本例子yc y(yc{}) 想说明的是 它只会调用一次构造函数,因为另一次进行复制消除~~~
懂了懂了,感谢回答![/quote] 请问yc{}这是什么写法呢?相当于什么?我在网上搜不到[/quote] 等价于yc(),产生一个临时无名对象,c++11加入的,感觉比yc()这样写好用哈。 [/quote] 十分感谢
coo135 2020-03-27
  • 打赏
  • 举报
回复
引用 14 楼 pokuwa 的回复:
[quote=引用 13 楼 pokuwa 的回复:] [quote=引用 12 楼 coo135 的回复:] 补充一次,原本例子yc y(yc{}) 想说明的是 它只会调用一次构造函数,因为另一次进行复制消除~~~
懂了懂了,感谢回答![/quote] 请问yc{}这是什么写法呢?相当于什么?我在网上搜不到[/quote] 等价于yc(),产生一个临时无名对象,c++11加入的,感觉比yc()这样写好用哈。
coo135 2020-03-27
  • 打赏
  • 举报
回复
3楼给的链接很详细了,自己看吧。 1:
引用 5 楼 pokuwa 的回复:
[quote=引用 1 楼 coo135 的回复:] C++标准规定,在对象的初始化中,当源对象是无名临时量对象时,就会进行复制消除(省略复制构造函数)。 比如:yc t(yc()); 什么都不会输出。
你好,我知道了我举的例子中少了一步复制构造函数是因为“复制消除”:方法体中的对象直接成为拷贝函数的参数,省略了中间一步临时变量。我还有两个问题: 1.我举的例子中的算是RVO吗? 2.能详细说说为什么yc y(yc())没有输出吗?yc y = yc()却有输出?两者有什么不同? [/quote] 1:是的,貌似RVO算复制消除的一种。 2:写错了,这个写法是一个声明~~自然没有输出;正确的写法yc y((yc())) 和yc y = yc()一样的。 我觉得这个例子的步骤是: shared_ptr<yc> y(new yc()); 会调用构造函数,输出yc construct; return *y ,*y会调用拷贝构造函数,输出copy construct& , 返回临时对象进行RVO,所以没有输出。 shared_ptr<yc> y 析构 deconstrutor 然后用临时初始化t,进行复制消除,没有输出。 析构,deconstrutor
竹剑单 2020-03-27
  • 打赏
  • 举报
回复
引用 13 楼 pokuwa 的回复:
[quote=引用 12 楼 coo135 的回复:] 补充一次,原本例子yc y(yc{}) 想说明的是 它只会调用一次构造函数,因为另一次进行复制消除~~~
懂了懂了,感谢回答![/quote] 请问yc{}这是什么写法呢?相当于什么?我在网上搜不到
竹剑单 2020-03-27
  • 打赏
  • 举报
回复
引用 12 楼 coo135 的回复:
补充一次,原本例子yc y(yc{}) 想说明的是 它只会调用一次构造函数,因为另一次进行复制消除~~~
懂了懂了,感谢回答!
coo135 2020-03-27
  • 打赏
  • 举报
回复
补充一次,原本例子yc y(yc{}) 想说明的是 它只会调用一次构造函数,因为另一次进行复制消除~~~
coo135 2020-03-27
  • 打赏
  • 举报
回复
引用 6 楼 真相重于对错 的回复:
yc y(yc()); 错误的语法。。。。
这个例子确实写错了,正确的写法应该是:yc y((yc())) 或者yc y(yc{}) 或者yc y(getY()),其实我本意是想写第二种的。但是表达的意思还是对的。
竹剑单 2020-03-27
  • 打赏
  • 举报
回复

yc getY() {
    shared_ptr<yc> y(new yc());
    return *y;
}

cout << typeid(getY()).name() << endl;
cout << typeid(yc()).name() << endl;
输出
class yc
class yc __cdecl(void)
看来是构造函数yc()不能这样用啊,我还以为yc()就是单纯的返回一个对象 感谢层主回答
真相重于对错 2020-03-27
  • 打赏
  • 举报
回复
yc y(yc());
	cout << &y << endl;
	return 0;
输出这个地址自然知道他是错误的语法,它只是一个声明,当然不会调用任何构造函数
真相重于对错 2020-03-27
  • 打赏
  • 举报
回复
编译器不知道你是定义一个叫y的yc实例,还是顶一个返回yc的函数????
真相重于对错 2020-03-27
  • 打赏
  • 举报
回复
yc y(yc()); 错误的语法。。。。
竹剑单 2020-03-27
  • 打赏
  • 举报
回复
引用 1 楼 coo135 的回复:
C++标准规定,在对象的初始化中,当源对象是无名临时量对象时,就会进行复制消除(省略复制构造函数)。 比如:yc t(yc()); 什么都不会输出。
你好,我知道了我举的例子中少了一步复制构造函数是因为“复制消除”:方法体中的对象直接成为拷贝函数的参数,省略了中间一步临时变量。我还有两个问题: 1.我举的例子中的算是RVO吗? 2.能详细说说为什么yc y(yc())没有输出吗?yc y = yc()却有输出?两者有什么不同?

64,654

社区成员

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

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