由临时对象引发的对常引用的思考
C++引用详解
关于临时对象返回和常引用问题
上代码
#include<stdio.h>
#include<iostream>
using namespace std;
class Test {
public:
Test() {
};
Test(int x1, int y1) :x(x1), y(y1) {
};
Test(Test& T) {
x = T.x;
y = T.y;
cout << "我是拷贝构造" << endl;
}
Test operator+(Test c) {
return Test(this->x + c.x, this->y + c.y);
}
void pri() {
cout << x << "---" << y << endl;
}
protected:
int x, y;
};
int main() {
Test o1(1, 2);
Test o2(2, 3);
Test r;
r = o1 + o2;
r.pri();
return 0;
}
为什么这里会报错呢,没有合适的拷贝构造函数
来看16行
return Test(this->x + c.x, this->y + c.y);
暂且称为Test(xxx),这里使用类名(参数列表)创建了一个无名对象,在这个函数体内,他是无名临时对象,函数体结束,就被销毁了。而return这一句,编译器内部的操作是
1.创建一个新对象,用拷贝构造函数存下这个无名对象
2.然后返回给调用这个函数的地方
即----->Test A(Test(this->x + c.x, this->y + c.y))
然后把A返回出去
r = o1 + o2就变成了r=A
那么在
Test A(Test(this->x + c.x, this->y + c.y))
这一句的拷贝构造函数中,就出现了需要注意的地方
Test(Test& T) {
x = T.x;
y = T.y;
cout << "我是拷贝构造" << endl;
}
如果拷贝构造函数像初学者一样写,那么编译就会报错,为什么呢,先来看下面的例子
int a=1;
int &b=a;
int &c=5;
&b=a这一句是合法的,而…&c=5是非法操作
声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。
a本身有地址,当然能引用,而5呢,复制完即销毁,没有地址,当然不能引用,若是c引用了,用着用着5没了,那c去哪??
那么想引用5怎么变呢,这里就需要使用常引用
const int &c=5;
用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性。
把5变成常量,存在常量区,那么一个常量自然可以引用咯
同理:对于临时变量Test(xxx)而言,想要引用它,就要把它变成常量,所以拷贝构造函数要改成常引用的形式
Test(const Test& T) {}
这样Test A(Test(this->x + c.x, this->y + c.y))才能成功调用拷贝构造函数