首页 > 编程笔记

C++引用(入门必读)

虽然指针的使用非常灵活和高效,但使用起来不是非常方便,很容易导致某些不易察觉的错误。C++ 引入了一种比指针更加便捷的方式,就是引用(Reference)。

引用的定义

引用也是一种数据类型,但是引用不能独立存在,必须依附某个变量。换句话说,定义一个引用,必须要指明是哪个变量的引用。

引用的定义方式类似于指针,只是用&取代了*,语法格式为为:
类型 &引用名 = 目标变量名;
&是引用修饰符,表示定义的是一个引用。

例如:
int a;
int &b = a;
引用一旦定义,就始终跟目标变量绑定,不能改变为其他变量的引用。假设 b 是变量 a 的引用,那么在 b 的生命周期内,b 始终都是 a 的引用,而不能再改变为其他变量的引用。

引用在其生命周期内完全可以替代其目标变量。也就是说,所有施加于引用上的操作,其效果都等同于直接对引用的目标变量进行操作。而且一旦目标变量的值发生了改变,引用的值也会发生同样的改变。

例如:
#include <iostream>

int main()
{
    int a = 10;
    int& b = a;
    std::cout << "b=" << b << ",a=" << a << std::endl;

    b = 20;
    std::cout << "b=" << b << ",a=" << a << std::endl;

    a = 100;
    std::cout << "b=" << b << ",a=" << a << std::endl;
   
    return 0; 
}
输出结果为:

b=10,a=10
b=20,a=20
b=100,a=100

读者可以把引用看做是变量的一个别名,定义一个引用只不过是给变量另外起了一个名字,这样两个名字拥有一个实体,对一个名字的操作自然也会影响到另外一个名字。

注意,和引用绑定的必须是先前定义好的某个变量,而不能是临时数据。例如:
int a;
int &b = a; // 正确

int &c = 12; // 错误,不能绑定临时数据

const引用

定义引用时也可以用 const 进行修饰,其结果为一个常引用,语法格式如下:
const 类型 &引用名 = 目标变量名;
举个简单的例子:
int a = 10;
const int& b = a;

a = 100; // 正确,变量 a 的值可以修改
b = 20; // 错误,不能通过常引用修改变量的值
示例中为 a 定义了 const 的引用 b,这样就可以限制通过引用 b 来修改目标变量 a,相当于给了这个别名只读不写的权限。

一般的引用在定义时必须有一个已经存在的变量,而常引用则没有这样的限制,可以定义一个临时数据的常引用。例如:
const int& a = 12; //正确

引用VS指针

和 C 语言相比,引用是 C++ 所特有的,在很多情况下,引用提供了与指针操作同等的功能,但是引用和指针还是有一些区别的。

引用必须与一个变量绑定,不存在没有任何目标的引用。因此如果在使用的过程中有可能出现什么都不指向的情况,则应该使用指针,可以把一个空值给指针。而若一个变量肯定指向某个对象,不允许为空,则可以使用引用。

引用仅仅是一个变量实体的别名。因此在使用引用之前,不需要检测其合法性。但指针在使用之前必须检测其指向的对象是否为空,不能对空指针进行取值操作。

指针可以重新赋值以重新指向新的对象,引用在初始化之后就不可以改变指向对象了。

指针可以指向数组的地址来替代数组使用,而引用不可以替代数组,引用只能指向数组中的某一个元素。

指针可以用于在堆上生成的对象,delete 的对象只能是一个指针,不能是引用。

推荐阅读