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

CString 有许多内部技巧,使其在传递给printf函数时看起来像一个普通字符串,尽管它实际上是一个类 -无需将其强制转换LPCTSTR为参数列表,例如,在varargs( ...) 的情况下,例如 aprintf。因此,试图理解 CString 实现中的单个技巧或函数是个坏消息。(数据函数是一个内部函数,它获取与字符串关联的“真实”缓冲区。)

有一本书,里面有 MFC Internals,IIRC 的 Blaszczak 书可能会涉及到它。

编辑:至于表达式实际转换为原始 C++ 的内容:-

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

这表示“假设您实际上是一起分配的项目数组中的第一个条目。现在,第二个项目实际上不是 a CString,它是 Unicode 或普通字符的普通 NUL 终止缓冲区 - 即 LPTSTR”。

表达同一件事的另一种方式是:

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

当您将 1 添加到指向 T 的指针时,您实际上添加了 1* sizeof T 根据原始内存地址。因此,如果一个 CString 位于 0x00000010 且 sizeof(CString) = 4,则数据将返回一个指针,指向从 0x00000014 开始的 NUL 终止的字符缓冲区数组

但仅仅脱离上下文理解这一件事并不一定是一个好主意。

为什么你需要知道?

于 2009-12-02T10:22:45.043 回答
1

它以 TCHAR 字符数组的形式返回紧接在 CStringData 结构之后的内存区域。

如果您查看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 回答