Вопрос

В заголовочном файле 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*)(&это[1]) указывать?

Структура CStringData используется в классе CString (http://www.koders.com/cpp/fid100CC41B9D5E1056ED98FA36228968320362C4C1.aspx).

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

Это было полезно?

Решение

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

Есть книга MFC Internals, которая посвящена этому, и IIRC, книга Блащака, может ее коснуться.

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

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

здесь говорится: «Представьте, что вы на самом деле первая запись в массиве элементов, размещенных вместе.Второй элемент на самом деле не является CString, это обычный буфер с нулевым завершением, содержащий символы Юникода или обычные символы, то есть LPTSTR".

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

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

Когда вы добавляете 1 к указателю на T, вы фактически добавляете 1* sizeof T в терминах необработанного адреса памяти.Таким образом, если у вас есть CString, расположенный по адресу 0x00000010 с sizeof(CString) = 4, данные вернут указатель на массив символов с нулевым завершением, начиная с 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*

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top