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*