什么时候使用点,箭头或双冒号引用C ++中的类的成员?
从其他C派生语言(如Java或C#)到C ++,首先非常令人困惑的是C ++有三种方法来引用类的成员: a::b
, ab
和a->b
。 我什么时候使用这些操作员中的哪一个?
(注意:这是一个Stack Overflow的C ++常见问题解答的入口,如果你想批评在这个表单中提供FAQ的想法,那么在这个开始所有这些的meta上的贴子将是这个地方的答案。那个问题在C ++聊天室中进行监控,常见问题解决scheme首先出现,所以你的答案很可能会被那些提出这个想法的人阅读)。
C ++使用三个不同的运算符来访问类或类对象的成员,即double冒号::
,即圆点.
,和箭头->
,用于三个不同的情况,总是明确的。 知道了这一点,你可以立即知道很多关于a
和b
只需在你看的任何代码中分别查看a::b
, ab
或a->b
。
-
a::b
仅用于b
是类(或名称空间)a
。 也就是说,在这种情况下,a
将始终是类(或名称空间)的名称。 -
只有在
b
是对象的成员(或对象的引用)时才使用ab
。 所以对于ab
,a
将始终是一个类的实际对象(或对象的引用)。 -
a->b
最初是(*a).b
的简写符号。 然而,->
是唯一一个可以被重载的成员访问操作符,所以如果a
是一个重载operator->
的类的对象(通常这样的types是智能指针和迭代器),那么它的含义就是类devise器实现。 总结:用a->b
,如果a
是一个指针,b
将是指针a
引用对象的成员。 但是,如果a
是一个重载此运算符的类的对象,则会调用重载的运算符函数operator->()
。
小字体:
- 在C ++中,声明为
class
,struct
或union
的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->()
,或者它是唯一可以重载的成员访问方法。