在C++中使用哪些字符串类?

Rom*_*n L 17 c++ string multithreading copy-on-write

我们有一个C++(MFC)的多线程桌面应用程序.目前开发人员使用CString或std :: string,可能取决于他们的心情.所以我们想选择一个实现(可能不是那两个).

MFC的CString基于写时复制(COW)习惯,有些人会声称这在多线程环境中是不可接受的(并且可能参考了这篇文章).我不相信这样的说法,因为原子计数器看起来非常快,并且这种开销在某种程度上可以通过减少内存重新分配来弥补.

我了解到std :: string实现依赖于编译器 - 它在MSVC中不是COW,但它是,或者是在gcc中.据我所知,新的C++ 0x标准将通过要求非COW实现并解决一些其他问题(例如连续的缓冲区要求)来解决这个问题.所以实际上std :: string看起来没有明确定义......

我不喜欢std :: string的一个简单示例:没有办法从函数返回一个字符串而没有过多的重新分配(复制构造函数如果按值返回,并且没有访问内部缓冲区来优化那么"返回通过引用"例如std::string& Result没有帮助".我可以使用CString执行此操作,方法是返回值(由于COW没有复制)或通过引用传递并直接访问缓冲区.再次,C++ 0x使用其右值引用进行救援,但我们不会在最近的特征中使用C++ 0x.

我们应该使用哪个字符串类?COW真的可以成为一个问题吗?是否有其他常用的字符串高效实现?谢谢.

编辑:我们目前不使用unicode,我们不太可能需要它.但是,如果有一些容易支持unicode的东西(不是以ICU为代价......),那将是一个加分.

Mat*_* M. 16

我会用std::string.

  • 促进与MFC的脱钩
  • 更好地与现有C++库交互

"价值回归"问题大多不是问题.编译器非常擅长执行返回值优化(RVO),在大多数情况下,按值返回时实际上会删除副本.如果没有,你通常可以调整功能.

COW被拒绝是有原因的:它没有扩展(好),并且所谓的速度提升还没有真正测量过(参见Herb Sutter的文章).原子操作并不像它们看起来那么便宜.使用单处理器单核时,它很容易,但现在多核是商用和多处理器广泛可用(用于服务器).在这种分布式体系结构中,存在多个需要同步的高速缓存,并且体系结构越分散,原子操作的成本越高.

是否CString实现小弦优化?这是一个简单的技巧,允许字符串不为小字符串(通常是几个字符)分配任何内存.非常有用,因为事实证明大多数字符串实际上很小,应用程序中有多少字符串长度小于8个字符?

所以,除非你给我一个明确显示使用净增益的真实基准,否则CString我更倾向于坚持标准:它是标准的,可能更好地进行优化.

  • "更好地与现有C++库交互" - 如果现有的C++库是MFC,CString提供更好的交互. (3认同)
  • @ 7vies:它是标准库中的标准,因此它可供所有开发人员使用.现在我承认我的特定环境对我来说是未知的,但是我仍然要谨慎地限制自己使用MFC特定的库.其中一个例子:TinyCpp(适用于TinyXml的cpp)使用`std :: string`. (2认同)

bar*_*noz 5

实际上,答案可能是"它取决于".但是,如果你使用MFC,恕我直言,CString使用会更好.此外,您还可以将CString与STL容器一起使用.但是,如果我使用带有CString的stl容器或MFC容器,它将导致另一个问题?使用CString将为您的应用程序提供灵活性,例如在unicode转换中.

编辑:此外,如果您使用WIN32 api调用,CString转换将更容易.

编辑:CString有一个GetBuffer()和关于允许您直接修改缓冲区的方法.

编辑:我在我们的SQLite包装器中使用了CString,并且格式化CString更容易.

    bool RS::getString(int idx, CString& a_value) {

//bla bla

        if(getDB()->getEncoding() == IDatabase::UTF8){
            a_value.Format(_T("%s"), sqlite3_column_text(getCommand()->getStatement(), idx));
        }else{
            a_value.Format(_T("%s"), sqlite3_column_text16(getCommand()->getStatement(), idx));
        }
        return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 我们不打算使用MFC容器:)我们已经使用STL了 (5认同)
  • @ 7vies:[因为没有人根据绳索实现std :: string.](http://stackoverflow.com/questions/2256160/how-bad-is-code-using-stdbasic-stringt-as-a-contiguous-缓冲)我同意`boost :: format`可以更好,但并非我们所有人都可以使用boost. (2认同)