引用是标识符的“别名”,或者这样说,如果为一个对象定义了引用,那么这个引用就相当于这个对象的“别名”。就类似于有个同学叫王明,但是他还有一个外号,叫大毛,那么这个大毛即是王明的别名。类比推论,引用即是对象的别名。
定义引用一般采取如下形式:类型 & 引用变量名 = 已定义的变量名
需要注意的是:
-
定义一个引用的时候,必须同时对它进行初始化,使它指向一个已存在的对象。
-
一个变量可以存在多个引用,即允许一个变量存在多个别名。
-
引用在初始化的时候引用一次,便不能再改变去引用其他的变量。
下边我简单对引用从用法、作用等方面解析:
一、简单用法
#include
using namespace std;
void test()
{
int a = 1;
cout << "a = "<< a << endl;
cout << "a-address: " << &a << endl;
int & A = a;
A = 3;
cout << "A = " << A << endl;
cout << "A-address: " << &A << endl;
cout << "a = " << a << endl;
}
int main()
{
test();
system("pause");
return 0;
}
程序运行结果如下图:
我们可以很清楚的看到,变量a和其引用A所指向的是同一个地址。所以,当引用A改变时,变量a的值也发生了变化。
如果变量或者引用具有常属性的话,又会怎么样呢?
#include
using namespace std;
void test()
{
const int b = 2;
cout << "b = " << b << endl;
//int &B = b; 错误,变量b有const修饰,其具有常属性,不能被直接引用
const int &B = b; //正确常引用可以引用常量
int c = 3;
const int C = c;
cout << "c = " << c << endl;
c = 5;
cout << "c = " << c << endl;
//C = 5;//错误,引用C具有常属性,不能被改变
}
int main()
{
test();
system("pause");
return 0;
}
二、引用作参及作为返回值
#include
using namespace std;
void swap(int &a, int &b)
{
int t = a;
a = b;
b = t;
}
int main()
{
int x = 5, y = 10;
cout << "x = " << x << ", y = " << y << endl;
swap(x, y);
cout << "x = " << x << ", y = " << y << endl;
system("pause");
return 0;
}
代码运行结果:
在这里,给函数传参时,进行了应用传参,所以,函数的形参实际上就是实参的别名,因此可以完成交换。
从上面的例子可以分析有,使用引用传递函数的参数,在内存中并没有生成临时的形参,而是直接对实参操作;而一般值传递的时候,在函数调用时,要给形参分配新的存储单元,形参变量是实参变量的临时拷贝;如果传递的是对象,还将调用拷贝构造函数;而使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元。
所以,应该注意到:
-
1.当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。
-
2. 如果不希望函数内部改变参数的值话,则可以在传参的时候用const进行修饰,变成常引用形参。
-
3. 如果,要调用返回值的话,则也可以根据需要用引用作为函数返回值。
-
4.不要返回一个临时变量的引用,因为局部变量在函数返回后会被销毁,所以被返回的引用指向了未知的空间,类似于“野指针”,程序会直接挂掉。
-
5. 如果返回对象出了当前作用域的话依旧存在,则最好采用引用作为返回值,因为这样更高效。
三、引用-指针
引用看似和指针一样,都是指向变量的,而且都能通过其改变变量本身的值,那么指针和变量是否一致呢?
很明显,这两个虽然相似,但是却并不相同。
简单总结一下,引用和指针的不同:
-
引用在定义时,必须进行初始化,即指向有效的变量,不能为空;而定义指针时不必赋值,其可以为空。
-
引用在定义并初始化后,就不能再去更改引用其他变量;指针变量的值可以随意改变(前提是没有const修饰)。
-
对于引用和指针的++(自增),--(自减)运算,其意义都不一样。
-
对引用对象进行sizeof求值,得到的是引用所指向的变量的大小;对指针进行sizeof求值,得到的是对象地址的大小。
引用总结
-
引用的存在,主要用于在函数参数传递中,解决复杂问题内部数据或对象的传递效率和空间使用率的问题。
-
使用引用传参,可以提高传递的效率,而且为了代码的安全性,可以通过const的修饰,保证了引用传递的安全性。
-
引用和指向相比较,引用更加安全,也更加高效;而指针比引用灵活,但是也更危险,稍有不对,便会造成很大的错误。所以在应用指针时要小心,定义指针时要进行初始化,在指针所指向的地址释放以后指针最好置空。