CString: Что означает (TCHAR *) (это + 1)? - PullRequest
1 голос
/ 02 декабря 2009

В заголовочном файле CString (будь то классы Microsoft или Open Foundation - 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).

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

Ответы [ 3 ]

2 голосов
/ 02 декабря 2009

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

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

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

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

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

Еще один способ выразить то же самое:

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

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

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

Зачем вам нужно , чтобы знать?

1 голос
/ 02 декабря 2009

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

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

...