std::string 的 + 和 += 适合少量拼接,+= 更高效;多类型混拼用 std::ostringstream,需注意清空流状态。

用 std::string 的 + 和 += 最直接
这是日常拼接最自然的方式,适合少量、已知类型的字符串拼接。它底层会自动管理内存,不用手动算长度或分配缓冲区。
常见错误是把 C 风格字符串字面量("hello")和 char* 混用,比如:std::string s = "a" + "b"; —— 这会编译失败,因为两个 const char* 相加是地址运算,不是字符串拼接。
- 正确写法:
s = std::string("a") + "b"或s = "a" + std::string("b") -
+=比+更高效,尤其在循环中追加时,避免重复构造临时对象 - 注意:频繁用
+拼接多个字符串(如 10+ 次)可能触发多次内存重分配,影响性能
大量拼接用 std::ostringstream
当你要把数字、布尔、自定义类型和字符串混在一起拼(比如日志格式化),std::ostringstream 是最稳的选择。它内部用缓冲区累积内容,最后调用 .str() 获取结果。
容易踩的坑是忘记清空流状态(比如之前发生过 failbit),导致后续写入失效;或者误以为 oss 会自动刷新缓冲——其实不会,必须靠 <code>.str() 触发提取。
立即学习“C++免费学习笔记(深入)”;
- 初始化后可直接
写入任意支持 <code>operator 的类型 - 想复用同一个
ostringstream对象?先调用oss.str("")清空内容,再调用oss.clear()重置状态位 - 性能上比反复
+=更好,尤其拼接项多且类型不一时
追求极致性能时考虑 std::string::append() 和 reserve()
如果你能预估最终字符串长度(比如拼接固定数量的固定长字符串),提前 reserve() 可彻底避免内存重分配。配合 append()(尤其是接受迭代器范围的重载),比 += 更明确、更可控。
典型反模式:s += a; s += b; s += c; —— 编译器不一定能优化掉中间临时对象,且每次 += 都要检查容量。
- 先
s.reserve(a.size() + b.size() + c.size() + 10);(+10 防小误差) - 再按顺序
s.append(a).append(b).append(c); -
append()有多个重载:支持子串、字符、C 字符串、迭代器对,比+更细粒度
C++17 起可用 std::string_view 避免不必要拷贝
当你只是“读”字符串(比如函数参数、中间拼接步骤),但不想触发 std::string 构造或拷贝,std::string_view 是轻量代理。它不拥有数据,只持有一个指针和长度。
关键限制:不能用它持有临时字符串字面量的生命周期以外的内容。比如 std::string_view sv = std::string("temp").c_str(); 是悬垂指针——std::string 析构后 sv 就失效了。
- 函数参数优先用
std::string_view替代const std::string&或const char* - 拼接时不能直接
sv1 + sv2,得转成std::string或用ostringstream - 和
reserve()+append()组合用,能进一步压低开销
std::string 的移动语义在 C++11 后已经让很多场景下的“避免拷贝”变得没那么紧迫——该用 + 就用,别过早优化。










