什么时候使用点,箭头或双冒号引用C ++中的类的成员?

从其他C派生语言(如Java或C#)到C ++,首先非常令人困惑的是C ++有三种方法来引用类的成员: a::baba->b 。 我什么时候使用这些操作员中的哪一个?

(注意:这是一个Stack Overflow的C ++常见问题解答的入口,如果你想批评在这个表单中提供FAQ的想法,那么在这个开始所有这些的meta上的贴子将是这个地方的答案。那个问题在C ++聊天室中进行监控,常见问题解决scheme首先出现,所以你的答案很可能会被那些提出这个想法的人阅读)。

C ++使用三个不同的运算符来访问类或类对象的成员,即double冒号:: ,即圆点. ,和箭头-> ,用于三个不同的情况,总是明确的。 知道了这一点,你可以立即知道很多关于ab只需在你看的任何代码中分别查看a::baba->b

  1. a::b仅用于b是类(或名称空间) a 。 也就是说,在这种情况下, a将始终是类(或名称空间)的名称。

  2. 只有在b是对象的成员(或对象的引用)时才使用ab 。 所以对于aba将始终是一个类的实际对象(或对象的引用)。

  3. a->b最初是(*a).b的简写符号。 然而, ->是唯一一个可以被重载的成员访问操作符,所以如果a是一个重载operator->的类的对象(通常这样的types是智能指针和迭代器),那么它的含义就是类devise器实现。 总结:用a->b ,如果a是一个指针, b将是指针a引用对象的成员。 但是,如果a是一个重载此运算符的类的对象,则会调用重载的运算符函数operator->()


小字体:

  • 在C ++中,声明为classstructunion的types被视为“类types”。 所以上面提到的全部三个。
  • 引用在语义上是对象的别名,所以我应该在#3中添加“或者引用一个指针”。 不过,我认为这会比有帮助的更混乱,因为指针( T*& )的引用很less被使用。
  • 点和箭头操作符可用于从对象引用静态类成员,即使它们不是对象的成员。 (感谢Oli指出这一点!)

为sbi的观点提出一个替代scheme3

a->b仅在a是指针时使用。 它是(*a).b的简写forms, a指向的对象的b成员。 C ++有两种指针,“常规”和智能指针。 对于像A* a这样的常规指针,编译器实现了-> 。 对于诸如std::shared_ptr<A> a智能指针, std::shared_ptr<A> a->shared_ptr类的成员函数。

理由:这个FAQ的目标受众不是写智能指针。 他们不需要知道->真的叫operator->() ,或者它是唯一可以重载的成员访问方法。