web-dev-qa-db-ja.com

MFC:std :: string vs CString?

MFCでのC++の使用。 C#のバックグラウンドから来ているので、私は通常、すべての文字列に文字列を使用します。クラスメンバー、メソッドパラメーター、メソッドの戻り値に使用します。

現在、C++には、std :: string、CString、char *、LPCTSTRなどがあります。データメンバー、メソッドパラメータ、およびメソッドの戻り値を設計するときに、どのタイプを使用する必要がありますか?使いやすさは重要であり、CStringはそれを提供しているようですが、私の本能は移植性のある標準に向けられていますが、私の優先事項のリストでは移植性はかなり低いです(現在)。また、文字列バッファを作成してメソッドや関数に渡すというcセマンティクスは好きではありません。

コーディングがすぐに簡単になるという観点から、CStringにはおそらくEdgeがあると思います。しかし、全体として、これを行うための「高コード品質」の方法は何ですか?

編集:

コード内のインターフェイスポイント(つまり、メソッドパラメーターと戻り値)について特に懸念しています。例えば。:

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

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

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

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

私は通常、コーディングスタイルを作業中のフレームワークに適合させて一貫性を保つことを好みます。そのため、MFC(長い間使用していません)を使用する場合は、CString(およびパブリックインターフェイスメソッドの関数引数としてLPCTSTR)を使用することを好みます。 Qtを使用する場合、STLコンテナーよりもQStringおよびQtのコンテナーを好みます。このようなフレームワークに直接関係しないものはすべて、文字列を処理する標準のC++方法であるstd::stringを使用します。

それらはすべてほぼ同等の機能を提供し(そして互いに簡単に変換可能であり)、特定のフレームワーク用にコードを記述した場合、それはとにかくそれに依存するため、それほど大きな違いはありません。したがって、移植性はそれほど大きくありません。大きな懸念。

単純なchar配列を気にしないでください!ちなみに、C++変数は自動的に参照されず、文字列のコピーにはかなりのコストがかかる可能性があるため、値ではなくconst参照(const std::string &caption)でオブジェクトを渡すようにしてください。

MFCは、CStringを使用することを期待して作成されました。これは、関数がパラメータを使用して文字列を返す場合に特に顕著です。たとえば、次の2つの呼び出しをGetWindowTextと比較します。

CString s1;
wnd.GetWindowText(s1);

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

ただし、2つの間での変換は悪くないため、ほとんどの場合は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));
7
Mark Ransom

移植性を重視し、C++を使用している場合は、std::stringを使用してください。必要がなければ、char配列を低レベルにする意味はありません。移植性を気にせず、プラットフォームが提供する文字列が必要な機能をより多く提供する場合は、必ずそれらを使用してください。実際には、プラットフォーム用にさらに最適化されている可能性があります。

3
rid

CStringは使用しないでください。スレッド化などに対して非常に脆弱なCOW実装を使用します。使用禁止 char*またはLPCTSTR(これはconst char*またはconst wchar_t*別の名前で)、彼らは彼ら自身の記憶を管理しないので。使う std::string8ビットコードポイントの場合またはstd::wstring Windowsの16ビットコードポイント(Unixの場合は32ビット)。

3
Puppy