在 C++ 中,何时使用点、箭头或双冒号来引用类的成员?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4984600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When do I use a dot, arrow, or double colon to refer to members of a class in C++?
提问by sbi
Coming from other C-derived languages (like Java or C#) to C++, it is at first very confusing that C++ has three ways to refer to members of a class: a::b
, a.b
, and a->b
. When do I use which one of these operators?
从其他C来源的语言(如Java或C#)到C ++到来,这是起初很困惑的是C ++有三种方式来引用类的成员:a::b
,a.b
,和a->b
。我什么时候使用这些运算符中的哪一个?
(Note: This is meant to be an entry to Stack Overflow's C++ FAQ. If you want to critique the idea of providing an FAQ in this form, then the posting on meta that started all thiswould be the place to do that. Answers to that question are monitored in the C++ chatroom, where the FAQ idea started out in the first place, so your answer is very likely to get read by those who came up with the idea.)
(注意:这是Stack Overflow 的 C++ FAQ 的一个条目。如果你想批评以这种形式提供 FAQ 的想法,那么开始所有这一切的 meta 上的帖子将是这样做的地方。答案该问题在C++ 聊天室中受到监控,FAQ 的想法首先在这里开始,因此您的答案很可能会被提出该想法的人阅读。)
回答by sbi
The three distinct operators C++ uses to access the members of a class or class object, namely the double colon ::
, the dot .
, and the arrow ->
, are used for three different scenarios that are always well-defined. Knowing this allows you to immediately know quite a lot about a
and b
just by looking at a::b
, a.b
, or a->b
, respectively, in any code you look at.
C++ 用来访问类或类对象的成员的三个不同的运算符,即双冒号::
、点.
和箭头->
,用于始终定义明确的三种不同场景。认识到这一点,您可以立即知道了很多有关a
,并b
只要看一眼a::b
,a.b
或a->b
分别,你看任何代码。
a::b
is only used ifb
is a member of the class (or namespace)a
. That is, in this casea
will always be the name of a class (or namespace).a.b
is only used ifb
is a member of the object (or reference to an object)a
. So fora.b
,a
will always be an actual object (or a reference to an object) of a class.a->b
is, originally, a shorthand notation for(*a).b
. However,->
is the only of the member access operators that can be overloaded, so ifa
is an object of a class that overloadsoperator->
(common such types are smart pointers and iterators), then the meaning is whatever the class designer implemented. To conclude: Witha->b
, ifa
is a pointer,b
will be a member of the object the pointera
refers to. If, however,a
is an object of a class that overloads this operator, then the overloaded operator functionoperator->()
gets invoked.
a::b
仅当b
是类(或命名空间)的成员时才使用a
。也就是说,在这种情况下a
将始终是类(或命名空间)的名称。a.b
仅当b
是对象的成员(或对对象的引用)时才使用a
。因此,对于a.b
,a
将始终是一个类的一个实际的对象(或对象的引用)。a->b
最初是 的简写符号(*a).b
。但是,->
是唯一可以重载的成员访问运算符,因此如果a
是重载的类的对象operator->
(常见的此类类型是智能指针和迭代器),则其含义与类设计者实现的无关。总结: witha->b
,如果a
是指针,b
将是指针a
所指对象的成员。但是,如果a
是重载此运算符的类的对象,则operator->()
调用重载的运算符函数。
The small print:
小字:
- In C++, types declared as
class
,struct
, orunion
are considered "of class type". So the above refers to all three of them. - References are, semantically, aliases to objects, so I should have added "or reference to a pointer" to the #3 as well. However, I thought this would be more confusing than helpful, since references to pointers (
T*&
) are rarely ever used. - The dot and arrow operators can be used to refer to static class members from an object, even though they are not members of the object. (Thanks to Oli for pointing this out!)
- 在 C++ 中,声明为
class
、struct
或 的类型union
被视为“类类型”。所以以上是指他们三个。 - 从语义上讲,引用是对象的别名,所以我也应该在 #3 中添加“或对指针的引用”。但是,我认为这会更令人困惑而不是有用,因为
T*&
很少使用对指针 ( ) 的引用。 - 点和箭头运算符可用于从对象引用静态类成员,即使它们不是对象的成员。(感谢 Oli 指出这一点!)
回答by MSalters
Suggesting an alternative for sbi's point 3
为 sbi 的第 3 点建议替代方案
a->b
is only used if a
is a pointer. It is a shorthand for (*a).b
, the b
member of the object that a
points to. C++ has two kinds of pointers, "regular" and smart pointers. For regular pointers such as A* a
, the compiler implements ->
. For smart pointers such as std::shared_ptr<A> a
, ->
is a member function of class shared_ptr
.
a->b
仅在a
是指针时使用。它是一个速记(*a).b
,所述b
的对象,该对象的构件a
点。C++ 有两种指针,“常规”指针和智能指针。对于诸如 之类的常规指针A* a
,编译器实现->
. 对于智能指针,例如std::shared_ptr<A> a
,->
是类的成员函数shared_ptr
。
Rationale: the target audience of this FAQ isn't writing smart pointers. They don't need to know ->
is really called operator->()
, or that it is the only member access method that can be overloaded.
基本原理:此常见问题解答的目标受众不是编写智能指针。他们不需要知道->
真的被调用operator->()
,或者它是唯一可以重载的成员访问方法。
回答by Hu Xixi
#include <iostream>
#include <string>
using namespace std;
class Human {
private:
int age;
public:
string name;
Human(int humanAge, string humanName)
: age(humanAge), name(std::move(humanName)) {}
void DoSomething() {
cout << age << endl;
}
static void DisplayAge(const Human& person) {
cout << person.age << endl;
}
// ...
};
int main() {
// Usage of Dot(.)
Human firstMan(13, "Jim"); // firstMan is an instance of class Human
cout << firstMan.name << endl; // accessing member attributes
firstMan.DoSomething(); // accessing member functions
// Usage of Pointer Operator (->)
Human* secondMan = new Human(24, "Tom");
cout << secondMan->name << endl; // accessing member attributes
secondMan->DoSomething(); // accessing member functions
cout << (*secondMan).name << endl; // accessing member attributes
(*secondMan).DoSomething(); // accessing member functions
// Usage of Double Colon (::)
Human::DisplayAge(firstMan);
firstMan.DisplayAge(firstMan); // ok but not recommended
secondMan->DisplayAge(firstMan); // ok but not recommended
delete(secondMan);
return 0;
}
From the coding example above, we see that:
* Accessing members(attributes and functions) from an instance(or object) using the dot operator (.
)
* Accessing members(attributes and functions) from a pointer to an object(or created by new
) using the pointer operator (->
)
* Accessing static member functions from class itself without having an object as a handle using the double colon (::
). [Note:you can also invoke the static member function from a instance with .
or ->
which is not recommended]
从上面的编码示例中,我们看到:
* 使用点运算符 ( .
)从实例(或对象)
访问成员(属性和函数) * 从指向对象(或创建者new
)的指针访问成员(属性和函数)使用指针运算符 ( ->
)
* 从类本身访问静态成员函数,而无需使用双冒号 ( ::
)作为句柄的对象。[注意:您也可以从实例中调用静态成员函数.
或->
不推荐]
回答by muditrustagii
Dot operator is used in direct member selection scenarios.
点运算符用于直接成员选择场景。
print(a.b)
Here, we are accessing b
, which is a direct member of an object a
. So, primarily, a
is an object and b
is a member (function/ variable etc) of a
.
在这里,我们正在访问b
,它是对象的直接成员a
。因此,主要a
是一个对象,并且b
是a
.
Arrow operator is used in indirect member selection scenarios.
箭头运算符用于间接成员选择场景。
print(a->b)
Here, we are accessing b
which is a member of the object, that is pointed to by a
. It is shorthand of (*a).b
and so here, a
is primarily a pointer to an object and b
is a member of that object.
在这里,我们访问的b
是对象的成员,即由 指向a
。它是(*a).b
and 所以在这里的简写,a
主要是一个指向对象的指针,并且b
是该对象的成员。
Double Colon (Scope) operator is used in namespace related direct member selection scenarios.
双冒号 (Scope) 运算符用于与命名空间相关的直接成员选择场景。
print(a::b)
Here, we are accessing b
which is a member of the class/namespace a
.So, primarily, a
is a class/namespace and b
is a member (function/ variable etc) of a
.
在这里,我们正在访问b
which 是类/命名空间的成员a
。因此,主要a
是类/命名空间,并且b
是 的成员(函数/变量等)a
。