C++中返回引用的函数可以作为等号的左值

引用的本质

在C++中,引用使用&修饰,相当于给变量取别名,有两个特点:1)引用必须初始化。2)引用初始化之后就不能更改。下面这两条语句都是错的:

int &a;
int &a=10;

正确的写法如下:

int b=10;
int &a=b;

这样a与b就相当于是同一块内存上数据的名称(别名)。本质上,引用是一个指针常量,即:

int &a=b;

等价于:

int * const a =&b;

这也解释了为什么引用不能更改,因为const限定了指针的指向不能变。在使用引用时,我们可以像使用普通变量一样赋值操作,编译器会完成解引用和取地址操作。

返回引用的函数

函数的返回值可以是引用,但是不要返回局部变量的引用,因为局部变量在栈上,函数结束后自动释放,而上面讲了,引用的本质是指针常量,那么再使用引用来访问该局部变量会产生乱码(编译器可能会保留一次使用,但第二次使用时就会变成乱码)。
那么如何正确返回引用呢,将返回变量放在全局区或者堆区就可以了,下面写两个函数演示一下:

int& test01(){
	static int a=10;
	return a;
}
int& test02(){
	int* a=new int(10);
	return *a;
}

void main(){
	int&c=test01();
	int&d=test02();
	cout<<c<<" "<<d<<endl;
}

运行之后输出的结果不出意外应该是:10 10

返回引用的函数作为等号的左值

在上面的例子中,把main函数里的代码改一下:

void main(){
	int&c=test01();
	int&d=test02();
	cout<<c<<" "<<d<<endl;
	test01()=100;
	test02()=1000;
	cout<<c<<" "<<d<<endl;
}

不出意外的话,结果应该是;
结果1
可以发现,函数返回引用时可以作为等号左值,相当于给返回的引用所指向的变量赋值,但是在全局区和堆区操作的结果不一致,之所以会这样是因为new这个关键字会在堆区开辟新的内存返回给引用,而static存储在全局区,不会开辟新内存,所以c所指向的内存会因为赋值发生改变,而d所指向的内存并不会发生赋值操作,因为test02()=1000;操作的是new开辟的一块新内存。
可以在函数中输出地址验证一下,将上述两个函数改成:

int& test01() {
	static int a = 10;
	cout << (int)(&a) << endl;
	return a;
}
int& test02() {
	int* a = new int(10);
	cout << (int)(a) << endl;
	return *a;
}
void main(){
	int&c=test01();
	int&d=test02();
	cout<<c<<" "<<d<<endl;
	test01()=100;
	test02()=1000;
	cout<<c<<" "<<d<<endl;
}

那么运行main函数的输出变成:
结果2
全局区的地址一样,堆区的地址变了。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值