3

このサイトによると、このコードが正しくない理由を知っている人はいますか:

CString First( "John" );
CString Last( "Doe" );

CString Name;

Name.Format( "%s %s", First, Last ); // Name may be garbage text

Name.Format( "%s %s", (LPCSTR)First, (LPCSTR)Last ); // this is the correct way

CString::Formatの Microsoft ドキュメントには、次のように記載されています。

...オプションの引数として文字列を渡す場合は、LPCTSTR として明示的にキャストする必要があります...

私はいつも「間違った」方法 (LPCSTR キャストなし) を使用していますが、問題はありませんでした。

ここで何か不足していますか?

4

4 に答える 4

3

引数を指定したときにキャストが行われないのと同様に、 Format 関数内でキャストが行われないためです。printf()

printfは、すでにデータ型が何であるかを示していると想定しているため、printf( "%d", a );キャストは行われません。a%da

がieに確実にCString変換されるようにするには、を返す の演算子を呼び出す引数をキャストする必要があります。CString のそれ以降のバージョンでは、文字列が格納されるため、キャストなしで記述した場合でも LPCSTR として出力されますが、確実にキャストを実行する方が適切です。LPCSTR%sCStringLPCSTR

または別の言い方をすれば、可変引数関数が引数を通過するとき、フォーマット指定子を使用して引数のサイズを認識します。フォーマット指定子が引数と一致しない場合、ガベージが発生します。CString には書式指定子がないため、CString を LPCSTR に変換する必要があります。

static_cast<LPCSTR>(First), static_cast<LPCSTR>(Last)ところで、C++で使用する必要があります

于 2013-01-16T11:39:46.117 に答える
2

LPCSTR にキャストすると、キャスト演算子が呼び出されますoperator LPCSTR()(これはoperator const char *().

LPCSTR を呼び出さないということは、CString オブジェクト全体を渡し、基になる構造体の最初の 32 ビットまたは 64 ビットを char ポインターとして盲目的に使用することを意味します。

要約LPCSTR(str)すると、適切な動作を確保するためにメソッドを呼び出しているのに対して、strブラインド ビットをいじっています。

于 2013-01-16T11:45:16.870 に答える
1

引数の型が不明な場合に MFC が実行しなければならない無駄な一時コピーを避けるために、効率的な理由からキャストが必要だと思います (CString は変更時に遅延コピーされます)。 .

秘訣は、参照カウンターなど、バッファー (TCHAR*) 以外のいくつかの重要なデータのために、CString メモリ割り当ての前にスペースを予約することです。 this

次に、可変引数関数に値で CString を渡すと、バッファー (ポインター) が「認識」されます。キャストは、コピー コンストラクターを呼び出さずに、バッファーだけを「抽出」します。

于 2013-01-16T12:10:37.693 に答える
1

サブクラス化された CString 引数を使用すると破損するためです。

于 2013-01-17T01:28:44.407 に答える