传指针比传值更能避免拷贝,因传值会触发o(n)级完整拷贝,而指针仅传递8字节地址;但需注意所有权、迭代器失效、边界检查等风险。

为什么传指针比传值更能避免拷贝
当函数参数是大型对象(比如 std::vector<int></int>、自定义结构体或矩阵类)时,按值传递会触发完整拷贝——构造函数 + 拷贝赋值,开销可能达 O(n)。而传 const T* 或 const T& 本质只传地址(通常 8 字节),不复制数据本身。
注意:指针本身不解决所有权问题,只是“借阅”;若需修改原对象且确保安全,优先用 T* 或 T&,而非 const T* 后再强制转换。
在递归/回溯算法中用指针复用缓冲区
像全排列、N 皇后这类算法常反复修改同一块数据。若每次递归都新建 std::vector<int></int>,栈上会堆积大量临时对象。改用指针指向一个外部预分配的缓冲区,能彻底消除中间拷贝。
常见错误现象:std::bad_alloc 或栈溢出,尤其在深度递归 + 大数组场景下。
- 把
std::vector<int> path</int>改为std::vector<int>* path_ptr</int>,并在入口处传入同一个实例 - 避免在递归函数内部对指针做
new/delete—— 容易泄漏或悬空 - 如果算法需多线程并行,不能共用同一缓冲区,此时应配合
thread_local或池化分配
STL 容器迭代器本质是指针,但要注意失效规则
std::vector::iterator 通常是原生指针或封装了指针的类,解引用开销极小。但误用会导致迭代器失效,引发未定义行为(如 Segmentation fault)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
使用场景:遍历中只读访问、原地修改元素(不改变容器大小)时,auto it = vec.begin() 是高效且安全的。
容易踩的坑:
- 调用
vec.push_back()后继续用旧it→ 迭代器失效 - 用
&vec[i]获取地址后,后续resize()或reserve()可能使该地址无效 -
std::list迭代器在插入/删除时不会失效,但随机访问慢;std::vector相反
自定义类中显式禁用拷贝,强制用户传指针或引用
若你的类管理大块堆内存(如图像缓冲区、稀疏矩阵),应主动禁止拷贝构造和赋值,防止意外深拷贝。这时调用方只能传 MyClass* 或 MyClass&。
实操建议:
- 在类定义中加
MyClass(const MyClass&) = delete;和MyClass& operator=(const MyClass&) = delete; - 提供
data()成员函数返回uint8_t*类型原始指针,供底层算法直接操作 - 若需共享所有权,用
std::shared_ptr<myclass></myclass>,但注意引用计数开销;纯性能敏感路径仍推荐裸指针 + 明确生命周期管理
复杂点在于:指针不自带边界检查,越界写入不会报错,只会破坏相邻内存——这类 bug 往往延迟暴露,调试成本远高于一次拷贝的开销。所以关键不是“所有地方都换指针”,而是清楚哪一层真正需要零拷贝,以及谁负责释放、何时释放。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










