1

CString ヘッダー ファイル (Microsoft または Open Foundation Classes - http://www.koders.com/cpp/fid035C2F57DD64DBF54840B7C00EA7105DFDAA0EBD.aspx#L77 ) には、次のコード スニペットがあります。

struct CStringData
{   
    long nRefs;
    int nDataLength;
    int nAllocLength;
    TCHAR* data() { return (TCHAR*)(&this[1]); };
    ...
};

(TCHAR*)(&this[1])は何を示していますか?

CStringData 構造体は、CString クラス (http://www.koders.com/cpp/fid100CC41B9D5E1056ED98FA36228968320362C4C1.aspx) で使用されます。

どんな助けでも大歓迎です。

4

3 に答える 3

2

printfCStringには多くの内部トリックがあり、実際にはクラスであるにもかかわらず、たとえば関数に渡されたときに通常の文字列のように見えます。たとえば、引数リストにキャストする必要はありません。たとえば、 ()LPCTSTRvarargs...printfの場合などです。したがって、CStringの実装で単一の個々のトリックまたは関数を理解しようとするのは悪いニュースです。(データ関数は、文字列に関連付けられた「実際の」バッファを取得する内部関数です。)

その中に入る本、MFC Internalsがあり、IIRCBlaszczakの本がそれに触れるかもしれません。

編集:式が生のC ++に関して実際に何に変換されるかについて:-

TCHAR* data() { return (TCHAR*)(&this[1]); };

これは、「実際には、一緒に割り当てられたアイテムの配列の最初のエントリであると仮定します。2番目のアイテムは実際にはCStringではなく、Unicodeまたは通常の文字の通常のNUL終了バッファです。つまりLPTSTRです」。

同じことを表現する別の方法は次のとおりです。

TCHAR* data() { return (TCHAR*)(this + 1); };

Tへのポインタに1を追加すると、実際には、生のメモリアドレスに関して1 *sizeofTが追加されます。したがって、sizeof(CString)= 4で0x00000010にあるCStringがある場合、データは0x00000014で始まるcharsバッファーのNULで終了する配列へのポインターを返します。

しかし、文脈から外れてこの1つのことを理解することは、必ずしも良い考えではありません。

なぜあなたは知る必要がありますか?

于 2009-12-02T10:22:45.043 に答える
1

CStringData構造体の直後にあるメモリ領域をTCHAR文字の配列として返します。

CString.cppファイルを見ると、なぜ彼らがこれを行っているのかを理解できます。

static const struct {
    CStringData data;
    TCHAR ch;
} str_empty = {{-1, 0, 0}, 0};

CStringData* pData = (CStringData*)mem_alloc(sizeof(CStringData) + size*sizeof(TCHAR));
于 2009-12-02T10:25:18.970 に答える
0

彼らはこのトリックを行うので、CString は通常のデータ バッファーのように見えます。getdata を要求すると、CStringData 構造をスキップし、char* のような実際のデータ バッファーを直接ポイントします。

于 2009-12-02T10:29:36.683 に答える