2015-02-08 2 views
-1

Здесь у нас есть простая структура узла, которая может быть использована для реализации двойного связанного списка.C++: Как найти объект-хост из указателя на переменную-член

template <class T> 
struct node { 

    node<T> *prev = NULL; 
    node<T> *next = NULL; 
    T data; 
}; 

Предположив мы не знаем, или иметь ссылку на объект узла/например, но у нас есть указатель на это данные членов. T;

Как можно ссылаться/найти объект узла узла с указателя на его данных?

+1

Вы не можете сделать это портативно. Вы можете найти способ взломать макрос 'offsetof' и' reinterpret_cast <> 'все вещи между' char * 'и' node * ', но это технически неопределенное поведение. Если вам нужно выразить двусторонние отношения, используйте обратные указатели от каждого дочернего узла до его родителя. –

+0

Вы спрашиваете, как найти «голову» в списке? 'T * data;' выглядит странно BTW. –

+0

У вас действительно есть указатель на член ('pointer == & node.data') или у вас есть указатель, хранящийся в этом элементе (' pointer == node.data')? Если последнее, вы не можете его найти. – StenSoft

ответ

1

Разрабатывая комментарий к StenSoft, если вы знаете только значение члена data, вы не сможете получить структуру, содержащую ее.

Но если вы знаете его адрес, скажем, T** member_addr вы можете найти node:

void * ma = static_cast<void *>(member_addr); // convert pointer to void * : legal 
intptr_t ima = static_cast<intptr_t>(ma); // convert void * to intptr_t : legal 
intptr_t ina = ima - offsetof(struct node, data); // legal by definition of offestof 
void * na = static_cast<void *>(ina); // convert intptr_t to void * : legal 
struct node *pn = static_cast<node *>(na); // convert void * to pointer : legal provided the initial void * pointer points to a correct object 

Конечно, все, что является единственным законным для C++ 11 или выше.

 Смежные вопросы

  • Нет связанных вопросов^_^