Which string classes to use in C++? Which string classes to use in C++? multithreading multithreading

Which string classes to use in C++?


I would use std::string.

  • Promote decoupling from MFC
  • Better interaction with existing C++ libraries

The "return by value" issue is mostly a non-issue. Compilers are very good at performing Return Value Optimization (RVO) which actually eliminates the copy in most cases when returning by value. If it doesn't, you can usually tweak the function.

COW has been rejected for a reason: it doesn't scale (well) and the so-hoped-for increase in speed has not been really measured (see Herb Sutter's article). Atomic operations are not as cheap as they appear. With mono-processor mono-core it was easy, but now multi-core are commodity and multi-processors are widely available (for servers). In such distributed architectures there are multiple caches, that need be synchronized, and the more distributed the architecture, the more costly the atomic operations.

Does CString implement Small String Optimization ? It's a simple trick that allows a string not to allocate any memory for small strings (usually a few characters). Very useful because it turns out that most strings are in fact small, how many strings in your application are less than 8-characters long ?

So, unless you present me a real benchmark which clearly shows a net gain in using CString, I'd prefer sticking with the standard: it's standard, and likely better optimized.


Actually, the answer may be "It depends". But, if you are using MFC, IMHO, CString usage would be better. Also, you can use CString with STL containers also. But, it will lead to another question, should I use stl containers or MFC containers with CString? Usage of CString will provide agility to your application for example in unicode conversions.

EDIT: Moreover, if you use WIN32 api calls, CString conversions will be easier.

EDIT: CString has a GetBuffer() and regarding methods that allow you to modify buffer directly.

EDIT: I have used CString in our SQLite wrapper, and formatting CString is easier.

    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;}


I don't know of any other common string implementations- they all suffer from the same language limitations in C++03. Either they offer something specific, like how the ICU components are great for Unicode, they're really old like CString is, or std::string trumps them.

However, you can use the same technique that the MSVC9 SP1 STL uses- that is, "swaptimization", which is the most hilariously named optimization ever.

void func(std::string& ref) {    std::string retval;    // ...    std::swap(ref, retval); // No copying done here.}

If you rolled a custom string class that didn't allocate anything in it's default constructor (or checked your STL implementation), then swaptimizing it would guarantee no redundant allocations. For example, my MSVC STL uses SSO and doesn't allocate any heap memory by default, so by swaptimizing the above, I get no redundant allocations.

You could improve performance substantially too by just not using expensive heap allocation. There are allocators designed for temporary allocations, and you can replace the allocator used in your favourite STL implementation with a custom one. You can get things like object pools from Boost or roll a memory arena. You can get tenfold better performance compared to a normal new allocation.