CСтрока:Что означает (TCHAR*)(это + 1)?
Вопрос
В заголовочном файле 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*