传引用更安全高效,因避免大型对象深拷贝开销且禁止空值绑定;const引用用于只读输入,非常用;非const引用要求实参为左值,确保可修改性与生命周期安全。

为什么传引用比传值更安全高效
传引用能避免对象拷贝开销,尤其对 std::vector、std::string 或自定义大对象,传值会触发深拷贝,可能拖慢性能甚至引发意外副作用。更重要的是,引用传递天然禁止空值——你没法把 nullptr 绑定到非 const 左值引用上,这比指针更早暴露调用方的错误。
但要注意:引用不是万能胶。它必须绑定到一个已存在的、有确定生命周期的对象;不能绑定到临时对象(除非是 const 引用,且生命周期会被延长,但仅限于函数参数场景)。
void func(const T& x) 和 void func(T& x) 的区别
核心在能否修改实参:
-
const T&:只读访问,最常用。适合所有“只读输入”场景,比如打印、计算、查找 -
T&:可写访问,调用方必须传左值(如变量),不能传字面量或临时对象。例如func(i)合法,func(42)编译失败 -
T&&(右值引用):不在此讨论范围,它用于移动语义,和“参数传递”目的不同
示例:
void print_size(const std::string& s) { std::cout
<pre class="brush:php;toolbar:false;">void append_exclaim(std::string& s) { s += "!"; } // OK: append_exclaim(my_str); 错误: append_exclaim("hello")
常见编译错误及原因
以下错误几乎都源于“试图把右值绑定到非常量左值引用”:
-
error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int':传了字面量或函数返回的临时对象 -
error: binding reference member 'x_' to stack memory:在类里存了局部变量的引用,函数返回后引用悬空 - 运行时崩溃但无编译报错:把局部数组/变量的引用返回给外部使用,典型悬垂引用
检查点:只要函数参数是 T&,就确认调用处传的是命名变量;若需支持字面量或临时对象,改用 const T&。
什么时候不该用引用传递
引用不是银弹。以下情况应优先考虑传值或指针:
- 小 POD 类型(如
int、double、std::pair<int></int>):传值通常更快,现代编译器还能做 RVO/NRVO 优化 - 需要表达“可选”或“未初始化”语义:引用无法为空,此时用
const T*或std::optional<t></t> - 跨模块边界(如 DLL 导出函数):引用 ABI 不稳定,容易因编译器/STL 版本差异导致二进制不兼容,优先用指针或值
真正容易被忽略的是生命周期管理——引用本身不延长所绑定对象的生命,哪怕你在函数里把它存进容器或返回出去,一旦原对象析构,引用立刻失效。这点比指针更隐蔽,因为编译器不报错。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











