引用是变量别名,必须初始化且不可重绑定;传参用int&比int*更安全高效,但只能绑定左值;const T&可绑定临时对象并延长其生命周期,非const引用则不行。

函数参数传引用比传指针更安全,但必须初始化且不能重绑定
引用不是对象,只是已有变量的别名;它没有独立内存,也不允许为空或中途换绑。传参时用 & 声明引用类型,编译器会直接操作原变量,避免拷贝开销,也杜绝了空指针解引用风险。
- 传
int&比传int*少一层间接寻址,性能略优(尤其对大对象) - 引用形参必须绑定到左值:不能传字面量(如
foo(42)会报错),也不能传临时对象(除非是 const 引用) - 函数内部对引用的修改就是对实参的修改,这点和指针一致,但语法上更干净——不用写
*x,直接用x - 如果只读不改,优先用
const T&:既能接受左值、右值,又防止误改,还避免拷贝
const 引用能绑定临时对象,普通引用不行
这是最常踩的坑。比如 std::string s = "hello"; func(s + " world"); 中,s + " world" 是临时对象,只能绑定到 const std::string&,不能绑定到 std::string& —— 否则编译失败,错误信息类似:error: cannot bind non-const lvalue reference to an rvalue。
- 临时对象生命周期短,非 const 引用试图“长期持有”它,语言层直接禁止
-
const T&是特例:编译器会延长临时对象生命周期至引用作用域结束 - 返回局部对象的引用是危险操作,哪怕加
const也不行(栈对象已销毁) - 想安全返回对象?直接返回值,现代 C++ 有 RVO/NRVO 或移动语义兜底
引用变量定义后不能重新赋值指向别的对象
引用一旦初始化,就永远绑定到那个变量。所谓“赋值”其实是给原对象赋值,不是换目标。这和指针的 = 行为完全不同。
int a = 10, b = 20; int& ref = a; // OK:绑定到 a ref = b; // 不是让 ref 指向 b!而是把 b 的值(20)赋给 a // 此时 a == 20,ref 仍绑定 a,b 不受影响
- 没有类似指针的
ref = &b;语法;引用没有地址再分配能力 - 数组、函数类型不能声明为引用变量(但可以是引用类型,如
int (&arr)[5]) - 结构体成员不能是引用(除非是 static 或在构造函数初始化列表里绑定)
在类成员中用引用需格外小心生命周期
类里存引用成员,本质是“我依赖外部某个变量活着”,一旦外部变量提前析构,这个引用就成悬空引用,行为未定义。
立即学习“C++免费学习笔记(深入)”;
- 必须确保被引用的对象生命周期 ≥ 引用所在对象的生命周期
- 通常只在构造函数初始化列表里绑定,且该引用应来自参数(传入的 const 引用或左值引用)
- 不要在类里存对局部变量、函数返回值(非 static)的引用
- 比起引用成员,多数场景下用指针(可判空、可重置)或智能指针更可控
引用看着简单,但它的“不可重绑”和“隐式生命周期依赖”才是真正容易出问题的地方。写的时候顺手,调试时找不到源头——往往是因为某处悄悄延长了临时对象寿命,或者某个引用早就指向了已释放的内存。










