CString: Что означает (TCHAR*)(это + 1)?

В заголовочном файле CString (будь то классы Microsoft или Open Foundation - http://www.koders.com/cpp/fid035C2F57DD64DBF54840B7C00EA7105DFDAA0EBD.aspx) есть следующий фрагмент кода

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

Любая помощь приветствуется.

3 ответа

Решение

CString имеет много внутренних трюков, которые делают его похожим на обычную строку при передаче, например, printf функции, несмотря на то, что на самом деле является классом - без необходимости приводить его к LPCTSTR в списке аргументов, например, в случае varargs ( ... ) например, в printf, Таким образом, попытка понять отдельный трюк или функцию в реализации CString - плохая новость. (Функция данных - это внутренняя функция, которая получает "настоящий" буфер, связанный со строкой.)

Есть книга, MFC Internals, которая входит в нее, и IIRC, книга Blaszczak, может коснуться ее.

РЕДАКТИРОВАТЬ: Что касается того, что выражение фактически переводит в терминах необработанного C++:

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

это говорит "представьте, что вы на самом деле первая запись в массиве элементов, выделенных вместе. Теперь второй элемент на самом деле не CString, это обычный NUL-концевой буфер либо с Юникодом, либо с обычными символами - т.е. LPTSTR".

Другой способ выразить то же самое:

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

Когда вы добавляете 1 к указателю на T, вы фактически добавляете 1* sizeof в терминах необработанного адреса памяти. Таким образом, если у вас есть CString, расположенная по адресу 0x00000010 с sizeof(CString) = 4, данные вернут указатель на завершенный NUL массив буферов символов, начинающийся с 0x00000014

Но понимание этой вещи вне контекста не обязательно является хорошей идеей.

Зачем тебе знать?

Он возвращает область памяти, которая находится сразу после структуры 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));

Они делают этот трюк, так что CString выглядит как обычный буфер данных, а когда вы запрашиваете getdata, он пропускает структуру CStringData и указывает непосредственно на реальный буфер данных, такой как char*

Другие вопросы по тегам