Skip to content

9.2 引用

引用(Reference)是一个已存在变量的别名(Alias)。引用一旦绑定到某个变量,就始终代表那个变量,对引用的所有操作等同于对原变量的操作。

int x = 42;
int& ref = x; // ref 是 x 的引用(别名)
std::cout << ref << std::endl; // 42
ref = 100;
std::cout << x << std::endl; // 100(通过 ref 修改了 x)

声明语法:类型& 变量名 = 初始值int& 表示「int 的引用」。

  1. 必须初始化 — 引用在声明时必须绑定到一个对象,不能只声明不初始化
int& ref; // 编译错误!引用必须初始化
  1. 不能重新绑定 — 引用一旦绑定,就不能改为引用其他对象
int a = 10, b = 20;
int& ref = a;
ref = b; // 这是把 b 的值赋给 a,不是让 ref 引用 b
std::cout << a << std::endl; // 20(a 的值被修改了)
  1. 没有空引用 — 引用必须绑定到有效对象,不存在「空引用」的概念

  2. 引用不是对象 — 引用本身不占用独立的内存空间(编译器在底层通常用指针实现,但语义上引用不是对象)

引用最常见的用途是作为函数参数,实现按引用传递(Pass by Reference):

// 按值传递:函数内部操作的是副本
void swapByValue(int a, int b) {
int temp = a;
a = b;
b = temp;
// 修改的是副本,对原变量无影响
}
// 按引用传递:函数内部操作的是原变量
void swapByRef(int& a, int& b) {
int temp = a;
a = b;
b = temp;
// 直接修改原变量
}
int main() {
int x = 1, y = 2;
swapByValue(x, y);
std::cout << x << " " << y << std::endl; // 1 2(未交换)
swapByRef(x, y);
std::cout << x << " " << y << std::endl; // 2 1(已交换)
return 0;
}

如果函数不需要修改参数,应使用 const 引用,既避免拷贝又防止意外修改:

void print(const std::string& s) { // 不拷贝,不修改
std::cout << s << std::endl;
// s = "test"; // 编译错误!const 引用不能修改
}

const 引用还有一个特殊能力:可以绑定到右值(临时对象):

const int& ref = 42; // 合法:const 引用可以绑定字面量
const std::string& r = "hello"; // 合法:绑定临时 string 对象
// int& ref2 = 42; // 错误!非 const 引用不能绑定右值

函数可以返回引用,避免返回值的拷贝:

class IntArray {
private:
int data[100];
public:
int& at(int index) {
return data[index]; // 返回引用,调用者可以直接修改
}
const int& at(int index) const {
return data[index]; // const 版本,只读
}
};
int main() {
IntArray arr;
arr.at(0) = 42; // 通过返回的引用赋值
std::cout << arr.at(0) << std::endl; // 42
return 0;
}

{% hint style=“danger” %} 与指针一样,不要返回局部变量的引用。局部变量在函数返回后被销毁,引用变成悬垂引用。 {% endhint %}

特性引用指针
初始化必须初始化可以不初始化(但不推荐)
空值不存在空引用可以为 nullptr
重新绑定不可以可以指向其他对象
语法直接使用,无需 *&需要 * 解引用、& 取地址
算术运算不支持支持(指针加减)
内存占用通常不独立占用占用一个指针大小
多级间接没有「引用的引用」有「指针的指针」(int**
  • 优先使用引用 — 大多数参数传递和返回值场景
  • 使用指针的场景
    • 需要表示「可能为空」的语义
    • 需要在运行时切换指向的对象
    • 需要指针算术(遍历数组等)
    • 与 C 语言接口交互
    • 动态内存管理(new / delete

{% hint style=“info” %} 现代 C++ 的建议:函数参数优先用 const 引用传递大对象,用值传递小对象和基本类型。需要修改参数时用非 const 引用。只在确实需要指针语义时才使用指针。 {% endhint %}