优先用 const 引用传递大对象以避免拷贝,引用不可重绑定、不占额外空间,返回局部变量引用会导致未定义行为,安全返回仅限成员/静态变量/长生命周期参数,引用与指针在迭代器失效时行为一致。

函数参数传入大对象时优先用 const 引用
传 std::vector、std::string 或自定义类这种可能几百字节的对象,值传递会触发拷贝构造,性能掉得明显。用 const T& 既避免拷贝,又防止误改原数据。
常见错误现象:void process(std::vector<int> v)</int> 在循环里反复调用,结果 CPU 花在拷贝上而不是计算上。
- 场景明确:只读访问、对象尺寸 > 2 个指针大小(通常 >16 字节)
- 不要写
T&(非常量引用)——调用方传临时对象会编译失败,比如process(get_data()) -
const T&能绑定临时对象,T&&(右值引用)才适合接管资源,别混用
需要重新绑定目标时只能用指针
引用一旦初始化就无法再指向别的对象,这是语言硬约束。想实现“先处理 A,再处理 B”,必须用指针。
常见错误现象:int a = 1, b = 2; int& ref = a; ref = &b; —— 这行根本编译不过,= &b 是赋值操作,不是重绑定。
- 指针可以随时改:
int* p = &a; p = &b; - 引用的地址在初始化后固定,底层通常不占额外空间(但非强制),而指针永远占 4 或 8 字节
- 涉及数组下标、偏移运算(如
p + 1)、或与 C API 交互时,也必须用指针
返回局部变量时绝不能返回引用
函数栈帧销毁后,局部变量内存失效,返回其引用等于交出一张过期车票——运行时大概率崩,或者返回垃圾值。
常见错误现象:const std::string& get_name() { std::string s = "test"; return s; },调用后 .c_str() 指向野内存。
- 能安全返回引用的情况只有:返回类成员、静态变量、或传入的参数引用(且调用方保证其生命周期更长)
- 不确定时,宁可返回值(现代 C++ 的 RVO/NRVO 通常能消除拷贝开销)
- 编译器不一定报错,尤其加了
const后更容易静默通过,靠 ASan 或 UBSan 才容易抓到
迭代器失效时引用和指针行为一致
容器重分配(如 std::vector 扩容)会让所有现存的指针、引用、迭代器全部失效。这不是引用或指针的锅,是容器语义决定的。
常见错误现象:循环中一边用 &v[i] 记住某个元素地址,一边调用 v.push_back(),之后解引用就未定义行为。
- 引用和指针在这里没区别——它们都只是内存地址的别名
- 别幻想“引用更安全”,只要底层地址被回收,引用照样崩
- 真要长期持有,存索引(
size_t)比存引用/指针更可靠(前提是容器不删中间元素)
事情说清了就结束。最常被忽略的是:引用不是“更安全的指针”,它只是不同语法糖;真正决定安全与否的,是对象生命周期是否可控。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










