由临时对象引发的对常引用的思考

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))才能成功调用拷贝构造函数

posted @ 2021-05-07 20:44  cheems~  阅读(27)  评论(0编辑  收藏  举报