2009-12-02 8 views
1

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

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

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

ответ

2

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

В книгу входит вход для входа в MFC Internals, а IIRC - книга Blaszczak.

EDIT: Что касается того, что выражение на самом деле переводится как с точки зрения сырья C++: -

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

это говорит «притвориться, что на самом деле первый элемент в массиве элементов выделяется вместе Теперь. второй элемент на самом деле не является CString, это обычный буфер с нулевым завершением либо Unicode, либо обычный символ, то есть LPTSTR.

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

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

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

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

Зачем вам необходимо знать?

+1

Это не относится к MFC, а к OFC. – kgiannakakis

+0

@kgiannakakis: Не следил за ссылками или не читал вопрос, до. Однако причины, вероятно, будут одинаковыми –

+0

@Ruben: Спасибо за это. Я думаю, что я понял это на основании вашего ответа и ответа кгяннакакиса. (этот + 1) в основном указывает на смещение в тип CString, где можно найти фактический контент. Оператор mem_alloc делает его более понятным. Это было всего лишь учебное упражнение. Отсюда вопрос. – Vino

1

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

@kgiannakakis: Didnt похоже на reimpl из CString MFC, поэтому причины, по которым они это сделали (чтобы можно было передать CString в '...' в printf без явного приведения в действие). –

+0

Okie, оператор mem_alloc делает его более понятным. Благодарю. – Vino

0

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