Differences between C++ References and Pointers: When to Use References?

一、基本概念:先搞懂“是什么”

在C++中,引用(Reference)和指针(Pointer)都与“变量的地址”或“别名”相关,但本质截然不同:

  • 引用:是变量的别名,它与原变量共享同一块内存空间,必须在定义时绑定到一个已存在的对象,且一旦绑定就无法再指向其他对象
    比如:int a = 10; int& ref = a; 这里 ref 就是 a 的别名,修改 ref 就等于修改 a

  • 指针:是一个存储地址的变量,它可以指向某个变量的内存地址,也可以为 nullptr(表示不指向任何对象)。
    比如:int a = 10; int* ptr = &a; 这里 ptr 存储的是 a 的地址,通过 *ptr 可以访问 a 的值。

二、核心区别:这5点必须分清

对比项 引用(Reference) 指针(Pointer)
语法形式 定义时用 &,无额外空间(如 int& ref = a; 定义时用 *&,本身占用内存(如 int* ptr = &a;
是否为空 不能为 nullptr(必须绑定对象) 可以为 nullptr(表示未指向任何对象)
初始化 必须在定义时初始化(如 int& ref = a; 可先不初始化(但通常需赋值合法地址或 nullptr
可变性 绑定后不可再指向其他对象(一生只能绑定一个) 可随时修改指向(如 ptr = &b;
解引用 直接使用(如 ref = 20; 需用 * 解引用(如 *ptr = 20;

三、关键细节:初学者常犯的错误

  1. 引用不能单独存在
    引用必须绑定到对象,不能像指针一样“悬空”。比如:int& ref; 是错误的,必须写成 int& ref = a;

  2. 指针可“空”,引用不可
    指针可以是 nullptr(表示无有效指向),例如 int* ptr = nullptr;;而引用若为 nullptr 会直接报错。

  3. 大小不同
    - 引用的大小与被引用类型相同(如 int& 大小是 int 的大小,4字节)。
    - 指针的大小固定(32位系统4字节,64位系统8字节),与指向的类型无关。

四、使用场景:什么时候用引用?什么时候用指针?

优先用引用的场景
1. 函数参数:避免大对象拷贝(如 void print(const string& s))。引用传递不会复制整个对象,效率更高。
2. 返回对象:避免返回大对象时的拷贝(如 string& getStr())。
3. 数组/容器别名:给数组或容器取别名(如 vector<int>& v = vec;)。
4. 重载运算符:如 string& operator[](int index)(类似C++标准库的数组访问)。

优先用指针的场景
1. 动态内存管理:需手动分配/释放内存(如 int* p = new int[10];)。
2. 需修改指针指向:比如函数需改变指针的指向(如 void swap(int* a, int* b))。
3. 返回空指针表示失败:若函数可能无有效结果,用指针返回 nullptr(如 Node* findNode(int key))。
4. 数组或容器的动态访问:通过指针遍历数组(如 int* p = arr; p++;)。

五、代码示例:用起来更直观

例1:引用与指针的修改对比

int a = 10;
int& ref = a;  // ref是a的别名
int* ptr = &a; // ptr指向a的地址

// 修改引用/指针,等价于修改原变量a
ref = 20;  // 等价于 a = 20
*ptr = 30; // 等价于 a = 30
cout << a << endl; // 输出:30(ref和ptr都修改了a)

例2:引用与指针的不可变性

int x = 10, y = 20;
int& ref = x;  // ref只能绑定x
ref = y;       // 合法:ref=20(修改x的值为20)
// ref = &y;    // 错误:引用不能重新指向其他对象!

int* ptr = &x;
ptr = &y;       // 合法:ptr现在指向y
*ptr = 30;      // 修改y的值为30
cout << y << endl; // 输出:30

六、总结:一句话记住

  • 引用:变量的“别名”,简单、安全,适合直接访问对象(避免拷贝)。
  • 指针:存储地址的“变量”,灵活但需手动管理(如空指针、内存释放),适合动态场景。

新手建议:优先用引用(安全、简洁),仅在必须处理空值或动态内存时用指针。

(注:本文代码基于C++11及以上标准,需注意编译器对引用的支持)

Xiaoye