Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MFC: std::string vs CString?

Tags:

Using C++ with MFC. Coming from a C# background I typically just use string for all, well, strings. I use them for class members, method parameters, and method return values.

Now in C++ I've got std::string, CString, char *, LPCTSTR, and more. As I design my data members, method parameters, and method return values which type(s) should I be using? Ease of use is important and CString seems to offer that but my instinct is toward portable standards although portability is pretty low on my list of priorities (now). Also, I don't like the c semantics of creating string buffers and passing them into methods and functions.

I think from an immediate ease of coding perspective CStrings probably have the edge. But, overall, what is the "high code quality" way to do this?

EDIT:

I'm especially concerned about the interface points in my code (i.e. method parameters and return values). E.g.:

Shape::SetCaption(const char *caption) {...}  Shape::SetCaption(CString caption) {...}  Shape::SetCaption(std::string caption) {...}  Shape::SetCaption(std::wstring caption) {...} 
like image 247
User Avatar asked May 24 '11 21:05

User


People also ask

Should I use CString or string?

Use string. cstring is so 1970's. string is a modern way to represent strings in c++. you'll need to learn cstring because you will run into code that uses it.

Is CString and string the same?

The two headers are completely different. cstring is inherited from C and provides functions for working with C-style strings (arrays of char terminated by '\0' ). string was born in C++ and defines the std::string class along with its non-member functions. It compares the numeric values of the characters.

What is the difference between CString and string h?

string. h places the identifiers in the global namespace, and may also place them in the standard namespace. While cstring places the identifiers in the standard namespace, and may also place them in the global namespace.

Does CString include string?

CString accepts NULL-terminated C-style strings. CString tracks the string length for faster performance, but it also retains the NULL character in the stored character data to support conversion to LPCWSTR . CString includes the null terminator when it exports a C-style string.


2 Answers

I usually prefer to adapt my coding style to the framework I'm working in to be consistent with it. So when I work with MFC (which i haven't for a long time), I prefer the use of CString (and LPCTSTR as function arguments in public interface methods). When working with Qt I prefer QString and Qt's containers over STL containers and for everything not directly related to such a framework I use std::string as it's the standard C++ way of handling strings.

It doesn't make such a huge difference, since they all offer more or less equal functionality (and are easily convertible into each other) and when code is written for a certain framework, it depends on it anyway, so portability is not such a huge concern.

Just don't bother with plain char arrays! And by the way, try to pass objects by const reference (const std::string &caption) and not by value, as in C++ variables are not automatically references and copying a string can get quite expensive.

like image 91
Christian Rau Avatar answered Oct 24 '22 00:10

Christian Rau


MFC was written with the expectation that you'd use CString. This is especially apparent when a function uses a parameter to return a string. For example, compare these two calls to GetWindowText:

CString s1; wnd.GetWindowText(s1);  std::wstring s2(SOME_MAX, 0); int len = wnd.GetWindowText(&s2[0], s2.size()); s2.resize(len); 

Converting between the two isn't bad though, so you might compromise by using std::wstring for most things and a temporary CString when necessary.

CString s3 = s2.c_str(); std::wstring s4 = s1; 

Edit: There may be a way to automate the temporary CString. Fair warning, this is a complete hack. I haven't tried this, so no guarantees - you'll probably get warnings about binding a temporary to a non-const reference, but you can turn those off.

class PopString : public CString { public:     PopString(std::wstring & final) : m_final(final)     {     }      ~PopString()     {         m_final = (PCTSTR) *this;     } private:     PopString(const PopString &) {}  // private copy constructor to prevent copying     PopString & operator=(const PopString &) {}  // private copy operator      std::wstring & m_final; };  std::wstring s5; wnd.GetWindowText(PopString(s5)); 
like image 31
Mark Ransom Avatar answered Oct 24 '22 00:10

Mark Ransom