7

当迭代指针的向量(或其他容器)时,使用:

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

或者

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

5 回答 5

10

在 C 语言中,没有区别。但是,在 C++ 中,->运算符可以重载,而成员选择.运算符不能。

因此 in(*foo)->bar *foo可以指定一个充当智能指针的类对象,尽管如果foo它是标准 C++ 指针容器上的迭代器,则不会发生这种情况,这意味着*foo计算结果为指针。

并且 in必须是一个类对象,其中包含一个名为(**foo).bar(可访问)的成员。**foobar

一元*也可以被重载(这就是迭代器foo,一个类对象,返回它引用的对象的方式)。

换句话说,表达式可以在含义上有所不同,但如果*foo是指向类/结构的指针,则从 C 语言继承的等价适用:(*ptr).member等价于ptr->member.

于 2012-11-08T19:08:45.553 回答
3

它们是等价的:定义的标准(用于指针)

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.
于 2012-11-08T19:35:52.080 回答
2

->,只是说将结构作为指针访问。.就像它只是一个结构一样。它是句法的 - 在功能方面没有区别。

编辑:你可以重载->让它做一些不同的事情,尽管假设你不这样做是一样的。不知道你为什么要这样做,但如果你这样做了,那么你必须使用额外的*.

于 2012-11-08T19:08:17.380 回答
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); }

  // ...
于 2012-11-08T19:28:38.230 回答
0

他们是一样的。例如,您可以根据使用的编码约定使用其中一种。

->*运算符可以重载,而.运算符不能。

于 2012-11-08T19:08:10.453 回答