const与引用&

一、const与引用&定义和初始化

1、用数值常量初始化常量引用

1.1测试程序

int main(void)
{
	const int& ra = 12;
	cout<<"ra的值为:"<<ra<<endl
		<<"ra的地址为:"<<&ra<<endl;
	return 0;
}
 

1.2运行结果

1.3现象

可以用常量初始化一个const引用,并且产生了临时对象。

1.4结论

用常量初始化一个const引用,引用ra是编译器隐式创建的int型匿名对象的别名。

 2、用相关类型变量初始化常量引用

类型相关:如果两个类型可以相互转换,则称这两个类型相关,只有相关类型之间才可以进行隐式或显式类型转换。

2.1测试程序

int main(void)
{
	short a = 1;
	const int& ra = a;
	a = 2;
	cout<<"a的值为:"<<a<<endl
		<<"ra的值为:"<<ra<<endl
		<<"a的地址为:"<<&a<<endl
		<<"ra的地址为:"<<&ra<<endl;
	return 0;
}

2.2运行结果


2.3现象

(1)a的值改变后,ra的值并没有改变;

(2)ra的内存地址和a的内存地址不一样;

2.4结论

ra并不是a的一个别名,编译器把short型数据转换成int型的匿名临时对象,ra是这个匿名临时对象的别名。

3、用相同类型变量初始化常量引用

3.1测试程序

int main(void)
{
	int a = 1;
	const int& ra = a;
	a = 2;
//	ra = 3; //Error:表达式必须是可修改的左值
	cout<<"a的值为:"<<a<<endl
		<<"ra的值为:"<<ra<<endl
		<<"a的地址为:"<<&a<<endl
		<<"ra的地址为:"<<&ra<<endl;
	return 0;
}

3.2运行结果


3.3现象

(1)a的值改变时,ra的值也会跟着改变;

(2)ra的内存地址和a是一样的;

(3)试图用ra = 3;修改ra的值是非法的;

3.4结论

(1)ra就是变量a的一个别名;

(2)ra前面的const的修饰符的意思是不能通过ra修改ra所标识的那块内存区域,但却可以通过a来修改,这和常量指针类似;

二、const与引用&作为函数形参

1、形参为非常量引用,实参为同类型变量

1.1测试程序

int add2(int& a)
{
	cout<<"add2函数中a的地址为:"<<&a<<endl;
	int c = a + 2;
	return c;
}
int main(void)
{
	int x = 1;
	cout<<"main函数中x的地址为:"<<&x<<endl;
	add2(x);
//	add2(4);  //Error:非常量引用的初始值必须为左值
	return 0;
}

1.2运行结果

1.3现象

(1)当实参为变量时,x和a的地址是一样的;

(2)当实参为常量时,编译器报错;

1.4结论

(1)当实参为变量时,形参就是实参的别名,占用同一块内存;

(2)当实参为常量时,编译器报错,这是因为不可以用const对象初始化非const引用;

2、形参为常量引用,实参为同类型变量和常量

2.1测试程序

int add2(const int& a)
{
	cout<<"add2函数中a的地址为:"<<&a<<endl;
	int c = a + 2;
	return c;
}
int main(void)
{
	int x = 1;
	cout<<"main函数中x的地址为:"<<&x<<endl;
	add2(x);
//	add2(4);  //可以通过编译
	return 0;
}

2.2运行结果

2.3现象

(1)形参改为const引用后,传入常量时不会报错;

2.4结论

(1)传入常量时不会报错,因为可以用const对象初始化const引用,这时编译器会产生匿名临时对象,这就是上面介绍的用数值常量初始化常量引用。

3、形参为常量引用,实参为相关类型变量

3.1测试程序

int add2(const int& a)
{
	cout<<"add2函数中a的地址为:"<<&a<<endl;
	int c = a + 2;
	return c;
}
int main(void)
{
	short x = 1;
	cout<<"main函数中x的地址为:"<<&x<<endl;
	add2(x);
	return 0;
}

3.2运行结果

3.3现象

(1)a的地址和x的地址并不一样;

3.4结论

(2)函数调用时对实参x进行了隐式类型转换,而且产生了临时对象,形参a是这个临时对象的别名;

三、关于常量引用型形参的几点总结:

1、为何要把形参声明成 const int & a形式

1.1、形参为 int& a,可不进行变量拷贝,节省内存,提高效率,但这种形参不允许传入像3这样的常量,所以要把形参声明为const int & a;

2、把形参声明为const int & a的优点:

2.1、a是实参的一个别名,没有进行内存拷贝,节省内存空间,提高了程序运行效率;

2.2、const修饰符可保证传入的实参在函数体内部不会被修改,如果形参是一个类对象的const&,则这个引用只能调用这个类的const成员函数,提高了程序的安全性;

2.3、使用const修饰符后,允许给函数传入常量,改善了程序的兼容性;

3、把形参声明为const int & a存在的问题:

3.1、传入常量时会伴随着临时对象的产生;

3.2、传入不匹配类型时(可隐式转换)会伴随着临时对象的产生;

参考资料:

[1] 刘光. 编码的法则:C++程序员不可不知的101条实用经验[M]. 北京:中国铁道出版社,2014. 39-42,85-89.

[2]  http://blog.csdn.net/kevinzhangyang/article/details/6638479


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值