如果我想将char c添加到字符串s的开头,那么以下良好做法是吗?
string s = "oo";
char c = 'f';
s = c + s;
在SO上的问题“ Prepend std::string ”中,建议这样做的答案没有得到比使用成员函数.insert()
建议的最高答案更好的答案。
除了效率之外,还有其他原因吗(s = c + s
效率不高,因为必须复制string s
的所有内容)?
答案 0 :(得分:3)
由于两者都执行相同的操作,为什么还有效率? c+s
将创建一个临时字符串,因此需要同时复制c
和s
中每个字符,并可能需要堆分配。然后将临时文件移到给定的对象中,该对象将释放其当前内存(如果有)。这些都不是便宜的操作。
相比之下,如果新字符的容量不足,insert
将仅 执行堆分配。由于您要在开始时进行插入,因此仍将继续进行复制。就是这样。它和插入连续数组头一样有效。
答案 1 :(得分:2)
s = c + s
操作将创建一个临时对象,可能会在堆上动态分配内存。执行所需的追加操作,然后将其复制回字符串变量。涉及更多的指令和内存操作。
诸如分配和取消分配内存之类的内存操作非常昂贵。
只有在字符串没有足够的连续内存可用时,Insert才会重新分配内存。最坏的情况是,它仍然与s = c + s
方法匹配。
尽管这并不是性能问题(考虑最坏的情况),但从程序员的角度来看,它更优雅,更容易理解。
答案 2 :(得分:0)
还要注意,没有什么可以阻止字符串的实现在两端允许有限的追加而无需移动内容的了。默认实现不执行此操作,但是某些实现可能会在您第一次添加前缀时在字符串的开头保留额外的空间,因此后续的前缀是“免费的”。这里有矢量实现。