(* это) -> метод () против (** это) .method

При итерации по вектору (или другому контейнеру) указателей, есть ли разница между и / или преимуществом, используя:

for (it = v.begin(); it != v.end(); ++it) {
(*it)->method();
}

или же

for (it = v.begin(); it != v.end(); ++it) {
(**it).method();
}

7

Решение

В языке Си нет никакой разницы. Однако в C ++ -> оператор может быть перегружен, тогда как выбор члена . оператор не может

Так в (*foo)->bar *foo может определить объект класса, который действует как умный указатель, хотя это не произойдет, если foo является итератором стандартного контейнера указателей C ++, что означает, что *foo оценивает указатель.

И в (**foo).bar, **foo должен быть объектом класса с членом под названием bar (который доступен).

Одинарный * также может быть перегружен (как итератор foo, объект класса, возвращает объект, на который он ссылается).

Другими словами, выражения Можно расходятся в значении, но если *foo является указателем на класс / структуру, тогда применяется эквивалентность, унаследованная от языка C: (*ptr).member эквивалентно ptr->member,

10

Другие решения

Они эквивалентны: как определено стандартом (для указателей)

5.2.5 Доступ к членам класса [expr.ref] 2: Для первого параметра (точка) первое выражение должно иметь полный тип класса. Для второй опции (стрелка) первое выражение должно иметь указатель на полный тип класса. Выражение E1-> E2 преобразуется в эквивалентную форму (* (E1)). E2; оставшаяся часть 5.2.5 будет касаться только первой опции (точка) .65 В любом случае выражение id должно называть члена класса или одного из его базовых классов.

Классы и переопределение операторов -> и * здесь не имеют значения, так как контейнер содержит указатели.

Таким образом:

(*it)->method();

// Is equivelent to:

(*((*it))).method();

// This is equivelent too:

(**it).method(); // thus both expressions are identical in this context.
3

Нет. -> просто говорит, чтобы получить доступ к структуре в качестве указателя. . действует так, как будто это просто структура. Это синактика — нет никакой разницы с точки зрения функциональности.

Изменить: вы можете перегрузить -> чтобы заставить его делать что-то другое, хотя, если вы этого не делаете, это то же самое. Не уверен, почему вы это сделаете, но если бы вы это сделали, вам пришлось бы снова разыменовать свою структуру, используя дополнительный *,

2

Они одинаковые. Например, вы можете использовать одно или другое в зависимости от используемых вами кодировочных соглашений.

-> а также * операторы могут быть перегружены, в то время как . оператор не может

0

В Ubuntu 12.04 итератор списка реализован следующим образом:

template<typename _Tp>
struct _List_iterator
{

// ...
reference
operator*() const
{ return static_cast<_Node*>(_M_node)->_M_data; }

pointer
operator->() const
{ return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); }

// ...
0
По вопросам рекламы [email protected]