MFC:std :: string vs CString?

时间:2011-05-24 21:42:33

标签: c++ string mfc cstring stdstring

将C ++与MFC一起使用。来自C#背景我通常只使用字符串表示所有字符串。我将它们用于类成员,方法参数和方法返回值。

现在在C ++中我有std :: string,CString,char *,LPCTSTR等等。当我设计我的数据成员,方法参数和方法返回值时,我应该使用哪种类型?易用性很重要,CString似乎提供了这一点,但我的直觉是针对便携式标准,尽管我的优先级列表(现在)的可移植性相当低。另外,我不喜欢创建字符串缓冲区并将它们传递给方法和函数的语义。

我认为从编码的角度来看,CStrings可能具有优势。但是,总体而言,“高代码质量”的方式是什么?

修改

我特别关注代码中的接口点(即方法参数和返回值)。 E.g:

Shape::SetCaption(const char *caption) {...}

Shape::SetCaption(CString caption) {...}

Shape::SetCaption(std::string caption) {...}

Shape::SetCaption(std::wstring caption) {...}

4 个答案:

答案 0 :(得分:19)

我通常更喜欢将我的编码风格调整到我正在使用的框架中以与之保持一致。因此,当我使用MFC(我已经很长时间没有)时,我更喜欢在公共接口方法中使用CString(和LPCTSTR作为函数参数)。在使用Qt时,我更喜欢QString和Qt的容器而不是STL容器,对于与这种框架没有直接关系的所有内容,我使用std::string,因为它是处理字符串的标准C ++方式。

它没有产生如此巨大的差异,因为它们都提供或多或少相同的功能(并且可以轻松地相互转换),并且当为某个框架编写代码时,无论如何它依赖于它,因此可移植性是没那么大的关注。

只是不要打扰普通的char数组!顺便说一下,尝试通过const引用(const std::string &caption)而不是通过值传递对象,因为在C ++变量中不会自动引用并且复制字符串会变得相当昂贵。

答案 1 :(得分:7)

编写MFC时期望您使用CString。当函数使用参数返回字符串时,这一点尤为明显。例如,将这两个调用与GetWindowText进行比较:

CString s1;
wnd.GetWindowText(s1);

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

虽然两者之间的转换也不错,所以你可能会因为大多数事情使用std :: wstring而在必要时使用临时CString来妥协。

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

编辑:可能有办法自动化临时CString。公平的警告,这是一个完整的黑客。我没有试过这个,所以没有保证 - 你可能会收到关于将临时绑定到非const引用的警告,但你可以关闭它们。

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

答案 2 :(得分:3)

如果您关心可移植性而且您正在使用C ++,请使用std::string。如果您不需要,则char数组不会低于低级别。如果您不关心可移植性,并且平台提供的字符串提供了您需要的更多功能,请务必使用它们。它们实际上可能更适合平台。

答案 3 :(得分:3)

不要使用CString。它使用COW实现,它非常容易受到线程之类的攻击。不要使用char*LPCTSTR(只是const char*const wchar_t*不同的名称),因为他们不管理自己的记忆。对于8位代码点使用std::string或在Windows上使用std::wstring用于16位代码点(对于Unix为32位)。