一、引用的概念
为对象起了另外一个名字(引用即别名)
二、使用引用要注意的地方
【notice】:
1.引用在使用之前必须有指向,也就是必须先初始化
2.不可以引用常量,也就是比如 int & a = 120;这样是绝对不允许的,因为引用是可以赋值的,既然你是常量的引用,而常量是不可以赋值的,这就矛盾了。
3.如果想引用常量,那么你可以让左值也是常量:const int & a = 120;这时候a是不可以修改的。
4.引用实际和被引用的量使用共同的内存空间,下面用程序验证
void demoRef1(void)
{
int val = 1024;
int & valRef = val;//引用的定义与赋值
cout << "val = " << val << "\t" << "valRef = " << valRef << endl;
//修改引用,看二者是否都变
valRef = 1;
cout << "val = " << val << "\t" << "valRef = " << valRef << endl;
//修改被引用的量,看二者是否都变
val = 2;
cout << "val = " << val << "\t" << "valRef = " << valRef << endl;
}
运行结果:这里可以看出引用和
5.将引用变量做参数时,函数将使用原始数据,而非副本(不像普通函数调用传递变量的副本)
举例说明:
//使用三种swap函数,只是传递的参数的不同
void Swap1(int num1, int num2)
{
int temp = num1;
num1 = num2;
num2 = temp;
}
void Swap2(int* p1, int* p2)
{
int ptemp;
ptemp = *p1;
*p1 = *p2;
*p2 = ptemp;
}
void Swap3(int& num1, int& num2)
{
int temp = num1;
num1 = num2;
num2 = temp;
}
//main函数
int main(void)
{
int num1 = 1, num2 = 2;
Swap1(num1, num2);
cout << num1 << '\t' << num2 << endl;
Swap2(&num1, &num2);
cout << num1 << '\t' << num2 << endl;
Swap3(num1, num2);
cout << num1 << '\t' << num2 << endl;
getchar();
return 0;
}
the result(结果):
可以看到,调用swap1显然是不是用的原变量,而是副本,Swap2是传入的参数指针,Swap3是引用
三、引用的好处
1.使用引用不需要测试有效性,因为它定义的时候就已经有指向,引用的效率也高
2.当数据所占内存较大时,建议使用引用
四、引用的应用补充:
1.关于返回引用类型:
【notice】:
a.千万不要返回局部变量的引用,因为局部变量会在使用后其内存被回收(是有生命周期的),如果你的引用接收了局部变量的值,假设其地址为0x11,当局部变量的内存回收后其内存又被其他的变量占用,由于引用始终0x11地址的值,所以无法保障其值没有改变
所谓内存回收,并不是将内存内部数据清零,而是指这块内存不是你程序申请的了。
int& Fun1() //返回引用类型的函数
{
int num = 10;
int & refNum = num;
return refNum;
}
void test(void)//用来占回收内存的程序
{
int a[10];
a[0] = 0;
}
void TestFun(void)
{
int & val = Fun1();
cout << val << endl; //打印占用前
test();
cout << val << endl;//打印占用后
}
//main
int main(void)
{
TestFun();
getchar();
return 0;
}
b.函数可以不返回值,默认返回传入的引用对象本身,(这个也取决于编译器,或者说取决于C++的版本)也就是说有的编译器编译通不过的是
2.数组的引用
这里我使用数组的引用进行了冒泡排序,我本来想的是通过传入数组的引用(节省空间,提高效率),然后再用new的方法接收它(目的是不改变原值,因为你排序归排序,别排完了数组都变了),但是虽然做出来了,数组的大小这个参数显得就很尴尬了,因为实际中一般你是不知道数组大小的,但是由于你传的是数组的引用,必须要有大小,(不说了,说多了都是悲痛啊,强烈建议大家用指针,这样效率既有保障,也能不改变原值)。
大家就把这个程序当成一个数组引用的传参就可以
//排序
void SortArr(int (&arr1)[10], int len)
{
int * ptrarr = new int[len];
int i, j;
ptrarr = arr1;
int temp;
cout << "原数组:" << endl;
for (i = 0; i < len; i++) {
cout << ptrarr[i] << ",";
}
for (i = 0; i < len - 1; i++) {
for (j = 0; j < len - 1 - i; j++) {
if (ptrarr[j] > ptrarr[j + 1]) {
temp = ptrarr[j];
ptrarr[j] = ptrarr[j + 1];
ptrarr[j + 1] = temp;
}
}
}
cout << endl;
cout << "排序后数组:" << endl;
for (i = 0; i < len; i++) {
cout << ptrarr[i] << ",";
}
cout << endl;
//delete [len]ptrarr;
}
//main
int main(void)
{
int arr[10] = { 2,5,4,6,8,1,0,9,7,3 };
SortArr(arr, sizeof(arr) / sizeof(int));
getchar();
return 0;
}