选引用还是指针参数看三点:是否可为空、是否需改指向、是否对接C接口;可为空或需重定向指针或对接C时必须用指针,其余情况优先引用。

选引用参数还是指针参数,核心就看三点:参数是否可为空、是否需要在函数内改指向、是否要对接C接口。其他情况基本都该用引用。
参数可能为 nullptr 时必须用指针
引用无法表示“无值”状态,声明时就必须绑定有效对象。一旦传入空值,编译器直接报错 error: invalid initialization of non-const reference。
- 常见场景:可选输出参数、回调中的可选上下文、资源句柄可能未初始化
- 错误写法:
void process(int& data)—— 调用方无法传“没有 data”的语义 - 正确写法:
void process(int* data),并在函数开头加if (data == nullptr) return; - 注意:即使只读,只要调用方逻辑上允许跳过该参数,也得用指针,不能靠默认参数 + 引用模拟
需要在函数内修改指针本身的值时只能用指针(或指针引用)
一级指针参数传入的是地址值的拷贝,修改形参指针本身(比如 p = new int(42))不会影响实参。但如果你真需要让调用方的指针变量被重定向,就得升级——要么用二级指针 int**,要么用指针引用 int*&。
- 典型需求:函数内分配内存并把地址回传给调用方
- 用二级指针:
void create_int(int** out_ptr) { *out_ptr = new int(100); },调用时传&ptr - 用指针引用更简洁:
void create_int(int*& out_ptr) { out_ptr = new int(100); },调用时直接传ptr - 纯引用参数
int&完全做不到这点——它连“指针变量”都不是,只是原变量的别名
对接 C 接口或需数组遍历时优先用指针
C 语言没有引用,所有系统 API、C 风格库(如 POSIX、OpenGL、FFmpeg)的函数签名全是 char*、void*、struct Foo* 这类。强行用引用会破坏 ABI 兼容性,甚至编译失败。
立即学习“C++免费学习笔记(深入)”;
- 数组首地址传递:虽然
int arr[10]传参可写成void f(int (&a)[10]),但实际中几乎没人这么干;更通用、更符合习惯的是void f(int* a, size_t n) - 多态向下转型:基类指针可安全转为派生类指针(带
dynamic_cast),而引用转换后无法再“退回去”,灵活性受限 - 性能上两者没差别:现代编译器对
int&和int*参数生成的汇编几乎一致,别迷信“引用更快”
最容易被忽略的一点是:引用绑定后不可重定向,这个约束不是语法糖,而是编译器强制执行的语义保证。哪怕你用汇编看,它也可能被优化成直接访问原变量地址——所以别试图用引用实现“运行时换目标”,那属于设计误用。


















