2014-10-27 3 views
0

Если у меня есть итератор list<Tree_Node*>::iterator iter, для определяемого пользователем класса Tree_Node, как вернуть объект, который имеет Tree_Node* точек, перейдя через итератор? Это в основном указатель на указатель, не так ли?Получение объекта, на который указывает двойной указатель

ответ

0

Вы разыменования итератора, чтобы добраться до Tree_Node* объекта, затем разыменования, что, чтобы добраться до Tree_Node:

**iter 

Допустим, у вас есть член Tree_Node::x, Вы можете обратиться к нему как:

(**iter).x 
(*iter)->x 

Это в основном указатель на указатель, не так ли?

В C++ абстракция итератора предназначена для того, чтобы иметь API, похожий на указатель ... на самом деле не имеет значения, как они реализованы, хотя для многих контейнеров это будет указатель.

+0

Для списка, что у меня есть, единственный раз, когда я добавить вещи к нему используя 'add()' функция. В функции я определяю Tree_Node *, чтобы добавить к ней, и у этого есть имя, но я делаю это только для того, чтобы избежать использования 'new' и беспокоиться о очистке. Вне функции это имя ничего не значит. Я планирую получить доступ к каждому элементу списка, используя цикл 'for'. Поскольку я не могу напрямую использовать формат (** iter) .x, который вы дали, должен ли я просто временно назначить каждому элементу указатель итератора (т. Е. «Tree_Node *») для переменной, чтобы у меня было имя для использования? Или есть лучший способ сделать это в цикле? – UnworthyToast

+0

Вы можете сделать что-то вроде 'for (auto & p: my_list) p-> tree_node_operation();' - таким образом 'p' - это имя, присвоенное каждому последующему значению итератора для использования в цикле. –

0

В C++ 11, вы могли бы сделать:

for(auto node : tree) 
    cout << node->data; 

Или в более старых версиях:

for(list<Tree_Node*>::iterator node = tree.begin(); node != tree.end(); node++) 
    cout << (*node)->data; 
0

Это в основном указатель на указатель, это не?

Абстрагирование является наоборот: Указатель представляет собой особый тип итератора (и то, что предположительно итераторы были смоделированы после), в то время как итератор абстракция. Но вывод справедлив, так же, как с указателем на указатель вы можете сделать:

list<Tree_Node*>::iterator iter; 
// assign something to iter 
Tree_Node* ptr = *iter; 
Tree_Node& node = *ptr; 

или сокращенно:

Tree_Node& node = **iter; 
+0

Интересно. Можете ли вы дать мне пример итератора, который НЕ является указателем? В этом семестре почти ничего, кроме указателей, трудно представить другой метод косвенного доступа к объекту. – UnworthyToast

+0

@UnworthyToast: Итератор, который мы используем здесь, уже такой пример. 'std :: list ' реализует связанный список, поэтому каждый из его узлов должен содержать указатели на следующий и предыдущие элементы. Кроме того, они не всегда могут удерживаться в непрерывной памяти. 'Std :: list :: iterator', вероятно, использует указатели внутри, но, например, разыменование не дает вам узел списка, а удерживаемый контент. 'operator ++()' не увеличивает внутренний указатель, а устанавливает его в тот, который находится в узле «next» -field. –

+0

Aha! Это меня всегда путало, но я думаю, что сейчас понял.Итак, вы говорите, что итераторы - это просто абстрактный тип данных, смоделированный после указателей, и на самом деле они часто являются указателями только с дополнительными перегруженными операторами. Но даже когда они сами не являются указателями, они обычно являются структурами, которые в определенной степени опираются на указатели, как в этом примере. У меня есть это право? – UnworthyToast

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