C++引用(入门必读)
虽然指针的使用非常灵活和高效,但使用起来不是非常方便,很容易导致某些不易察觉的错误。C++ 引入了一种比指针更加便捷的方式,就是引用(Reference)。
引用的定义方式类似于指针,只是用
例如:
引用在其生命周期内完全可以替代其目标变量。也就是说,所有施加于引用上的操作,其效果都等同于直接对引用的目标变量进行操作。而且一旦目标变量的值发生了改变,引用的值也会发生同样的改变。
例如:
注意,和引用绑定的必须是先前定义好的某个变量,而不能是临时数据。例如:
一般的引用在定义时必须有一个已经存在的变量,而常引用则没有这样的限制,可以定义一个临时数据的常引用。例如:
引用必须与一个变量绑定,不存在没有任何目标的引用。因此如果在使用的过程中有可能出现什么都不指向的情况,则应该使用指针,可以把一个空值给指针。而若一个变量肯定指向某个对象,不允许为空,则可以使用引用。
引用仅仅是一个变量实体的别名。因此在使用引用之前,不需要检测其合法性。但指针在使用之前必须检测其指向的对象是否为空,不能对空指针进行取值操作。
指针可以重新赋值以重新指向新的对象,引用在初始化之后就不可以改变指向对象了。
指针可以指向数组的地址来替代数组使用,而引用不可以替代数组,引用只能指向数组中的某一个元素。
指针可以用于在堆上生成的对象,delete 的对象只能是一个指针,不能是引用。
引用的定义
引用也是一种数据类型,但是引用不能独立存在,必须依附某个变量。换句话说,定义一个引用,必须要指明是哪个变量的引用。引用的定义方式类似于指针,只是用
&
取代了*
,语法格式为为:类型 &引用名 = 目标变量名;
&
是引用修饰符,表示定义的是一个引用。例如:
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 的对象只能是一个指针,不能是引用。