C++引用问题
时间:2011-12-07
来源:互联网
using namespace std;
class A
{
public:
A(int i){cout << "执行构造函数创造一个对象\n";x=i;}
A(A&a){x=a.x;cout << "执行复制构造函数创建一个对象\n";}
~A(){cout << "执行析构函数释放一个对象\n";}
int get(){return x;}
private:
int x;
};
A func()
{
cout << "跳转到func函数中:\n";
A a(23);
return a;
}
int main()
{
A &r=func();
cout << "对象a的副本的地址:" << &r << endl;
cout << r.get() << endl;
return 0;
}
编译器报错:
\we\main.cpp|21|error: invalid initialization of non-const reference of type 'A&' from a temporary of type 'A'|
求大侠帮忙,看看那里错了?
作者: q243021856 发布时间: 2011-12-07
他的意思是这里有错,func()返回的是一个临时对象,一个临时对象不能被一个非const 的引用绑定。
他是这么说的。
作者: mingliang1212 发布时间: 2011-12-07
作者: moonclock 发布时间: 2011-12-07
作者: huai_f 发布时间: 2011-12-07
作者: q243021856 发布时间: 2011-12-07
作者: q243021856 发布时间: 2011-12-07
可是a消亡了,不是函数返回的时候还会产生一个副本吗
是的,但是那个副本是临时的(通常用一次后就析构了)。而现在A &r = 临时变量; 也就是说r是一个临时变量(本尊)的别名(化身),但是这个操作完成后,那个临时变量就不存在了,本尊都不存在,化身也就木有任何意义了。
作者: pathuang68 发布时间: 2011-12-07
回到你的问题,关于出错的原因:函数func返回值是一个A类型的临时变量,C++是不允许一个non-const-reference绑定到一个临时变量的。MSVC如果允许的话那就是不符合标准。
顺便提一下,如果是non-const reference绑定到临时变量的话,后者的生命周期是引用变量的周期。
可是a消亡了,不是函数返回的时候还会产生一个副本吗
作者: tonywearme 发布时间: 2011-12-07
可是a消亡了,不是函数返回的时候还会产生一个副本吗
A &r=func();
你的编译器认为,临时对象是不可以更改的。所以临时对象只能被const 引用绑定。如下:
const A& r= func();
作者: mingliang1212 发布时间: 2011-12-07
顺便提一下,如果是const reference绑定到临时变量的话,后者的生命周期是引用变量的周期。
你的理解正确。
回到你的问题,关于出错的原因:函数func返回值是一个A类型的临时变量,C++是不允许一个non-const-reference绑定到一个临时变量的。MSVC如果允许的话那就是不符合标准。
顺便提一下,如果是non-const reference绑定到临时变量的话,后者的生命周期是引用变量的周期。
引用 5 楼 q243021856 的回复:
可是a消亡了……
作者: tonywearme 发布时间: 2011-12-07
作者: q243021856 发布时间: 2011-12-07
作者: q243021856 发布时间: 2011-12-07
可是书上说:临时变量的生命期不会少于那个引用变量,为什么楼上的说“后者的生命周期就是引用的变量的生命期呢”
作者: tonywearme 发布时间: 2011-12-07
const A& r= func();
什么是const reference?
作者: tonywearme 发布时间: 2011-12-07
作者: q243021856 发布时间: 2011-12-07
可是书上说:临时变量的生命期不会少于那个引用变量,为什么楼上的说“后者的生命周期就是引用的变量的生命期呢”
那样的写法,可以理解为:引用r就是临时变量
作者: pathuang68 发布时间: 2011-12-08
那什么情况下会像楼上那样用const A& r = func();
没有必要用const A& r = func();
这样的写法,应该用 A r = func();代替。
引用一般在函数参数传递的时候常用。其他地方一般不用,除非变量名字很长之类的无聊原因。
作者: mingliang1212 发布时间: 2011-12-08
作者: q243021856 发布时间: 2011-12-08
不过本人认为:
A &r=func();
上述语句如果改为A r = func();或许lz的编译器不会出错。
虽然func()返回的是一个临时对象,但是A r = func();执行的是一个拷贝传值的方式,所以应该不会出错(在《Thingking in C++》第一卷中的引用一章也用该模式,并给出了原理,p253,最近刚好看到这一部分)。
引用必须和存储单元联系,即访问引用时,实际就是在访问那个存储单元,所以本人怀疑func()返回的对象的隐藏指针虽然被销毁了,可实际的地址中的内容未被覆盖,故引用后的对象还是可用。
当然,应该尽量避免此种情况的发生。
作者: likid1412 发布时间: 2011-12-08
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28