支持通配符SSL证书、多域名证书、IP证书。适配ACME接口, 支持Zerossl、Let's Encrypt和Google等渠道。登录已有账号
2026-07-15 12:00:51 C++ std::vector 参数传递 性能优化
写 C++ 久了,有些东西回头看会觉得理所当然,但刚上手的时候真不一定能反应过来。比如一个很简单的场景:函数要接收一个 std::vector,到底该按值传、按引用传,还是加个 const 传常量引用?代码怎么写都行,编译器多数时候也不报错,但线上数据量一上来,差别就出来了。
一开始我也没太当回事,觉得 vector 嘛,传进去就行了。直到有次处理一个日志分析,vector 里塞了几十万条记录,每次调函数都卡一下,追下来才发现是没加引用,每次都傻傻深拷贝了一份。
所以后来再写类似的东西,就会习惯性多想一步。
下面分开说这三种传法。
按值传递
写法就是 void f(std::vector<int> vec)。
调用的时候,实参的整个 vector 会被复制一份,栈上构造一个新的 vector 出来。你在函数里面怎么折腾这份副本都没关系,原数据不会变。
#include <vector>
#include <iostream>
void processVector(std::vector<int> vec) {
vec.push_back(42);
}
int main() {
std::vector<int> data = {1, 2, 3};
processVector(data);
// data 还是 {1, 2, 3}
for (int num : data) {
std::cout << num << " ";
}
return 0;
}
好处很明显:数据隔离,不用担心副作用。缺点也足够致命:当 vector 很大的时候,拷贝花的时间和内存都直线上升。我之前那个几十万条的场景,就是典型的反面教材。
所以这种写法只适合 vector 非常小、或者你真的需要一个独立副本去改的时候。如果你只是读数据,那就别这么干。
常量引用传递
如果函数只打算读 vector,不修改,那就写 const std::vector<int>& vec。
不拷贝,直接绑定到原对象,但因为有 const 修饰,你想改也改不了,编译器会直接拦。
#include <vector>
#include <iostream>
void readVector(const std::vector<int>& vec) {
for (int num : vec) {
std::cout << num << " ";
}
}
int main() {
std::vector<int> data = {1, 2, 3};
readVector(data);
return 0;
}
这个没有额外的运行时开销,也不存在误改的问题。日常写代码里,读多写少,这是用得最多的方式。
遍历、求和、打印、判断是否包含某个值,都用 const & 就对了。
不过有一点得注意:函数内部拿到的是一份只读视图,你不能通过它去调 push_back 或者 clear 这类非 const 成员函数。
如果业务逻辑确实需要改 vector,那这条路就走不通。
引用传递
当你确实要在函数内部修改原 vector 的时候——比如排序、去重、追加元素——直接用 std::vector<int>& vec。
同样不拷贝,直接操作原对象。
#include <vector>
#include <iostream>
void modifyVector(std::vector<int>& vec) {
vec.push_back(42);
}
int main() {
std::vector<int> data = {1, 2, 3};
modifyVector(data);
// data 现在是 {1, 2, 3, 42}
for (int num : data) {
std::cout << num << " ";
}
return 0;
}
好处是零拷贝,也足够灵活。缺点在于,函数的行为会直接作用到外部,如果你写了一大段逻辑,忘了这个 vector 会被改到,就很容易出 bug。尤其是多人协作的时候,调用方可能完全没预料到数据会被动。
这个地方容易绕进去的,是有些人会觉得“非 const 引用不安全,能不用就不用”,但实际业务里,有些地方就是需要原地修改,强行用别的方式反而让代码绕来绕去更难读。
核心就是:用的时候自己心里要有数,知道这个引用意味着什么。
实际写的时候,我倒不会严格按什么决策树来选,基本就是问自己两个问题:
如果不需要改,直接上 const &;如果要改,并且改动就应该作用于原数据,那就用非 const 引用;只有在你明确需要一个副本去实验、又不想影响外部的时候,才考虑按值传递,同时确认数据量别太大。
很多地方的性能问题,就是从这种不起眼的传参选择开始的。写的时候多留一个心眼,后面能少踩不少坑。
从越界导致的未定义行为聊起,理清NULL误用,整理at()、边界检查等安全写法,以及几个能让程序稳一点的小优化。
你的ShardingSphere-JDBC连接是否频繁“失联”?本文将带你一探究竟,揭示连接关闭背后的三大元凶:连接池陷阱、执行引擎迷思和隐形超时。我们提供一套系统的优化策略,包括精细化Druid参数配置、maxConnectionSizePerQuery的巧妙运用以及数据库超时参数的智慧调整,让你的数据管道畅通无阻。
深入探讨在高流量场景下,Web系统如何通过负载均衡、缓存、异步处理和数据库优化等技术手段,实现高性能、高可用和弹性伸缩,以应对“春运级”的用户洪峰。