提问人:sbi 提问时间:2/13/2011 最后编辑:Communitysbi 更新时间:1/24/2020 访问量:102912
何时使用点、箭头或双冒号来引用 C++ 中的类的成员?
When do I use a dot, arrow, or double colon to refer to members of a class in C++?
问:
从其他 C 派生语言(如 Java 或 C#)到 C++,起初非常令人困惑的是,C++ 有三种方式来引用类的成员:、 和 。何时使用这些运算符中的哪一个?a::b
a.b
a->b
答:
C++ 用于访问类或类对象成员的三个不同运算符,即双冒号、点和箭头,用于始终定义良好的三种不同方案。知道这一点可以让你立即知道很多,并且只需在你查看的任何代码中分别查看 、 或 。::
.
->
a
b
a::b
a.b
a->b
a::b
仅当是类(或命名空间)的成员时才使用。也就是说,在这种情况下,将始终是类(或命名空间)的名称。b
a
a
a.b
仅当是对象的成员(或对对象的引用)时才使用。因此,for 将始终是类的实际对象(或对对象的引用)。b
a
a.b
a
a->b
最初是 的简写符号。但是,是唯一可以重载的成员访问运算符,因此,如果是重载的类的对象(常见的此类类型是智能指针和迭代器),则含义是类设计器实现的任何内容。总结:如果 是指针,则将是指针所引用的对象的成员。但是,如果是重载此运算符的类的对象,则调用重载运算符函数。(*a).b
->
a
operator->
a->b
a
b
a
a
operator->()
小字:
- 在 C++ 中,声明为
类
、结构
或联合
的类型被视为“类类型”。所以以上指的是他们三个。 - 从语义上讲,引用是对象的别名,所以我也应该在#3中添加“或引用指针”。但是,我认为这比帮助更令人困惑,因为很少使用对指针 (
T*&
) 的引用。 - 点和箭头运算符可用于引用对象中的静态类成员,即使它们不是对象的成员。(感谢 Oli 指出这一点!
评论
.
->
operator*()
operator->()
->
operator*
.
operator->
建议 SBI 第 3 点的替代方案
a->b
仅当指针时才使用。它是 的简写,指向的对象的成员。C++ 有两种指针,“常规”指针和智能指针。对于常规指针,例如 ,编译器实现 .对于智能指针,例如 ,是类的成员函数。a
(*a).b
b
a
A* a
->
std::shared_ptr<A> a
->
shared_ptr
基本原理:本 FAQ 的目标受众不是在编写智能指针。他们不需要知道 ->
实际上被称为 operator->(),
或者它是唯一可以重载的成员访问方法。
评论
+1
->
#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;
}
从上面的编码示例中,我们看到:
* 使用点运算符 () 从实例(或对象)访问成员(属性和函数) * 使用指针运算符 () 从指向对象(或由 ) 创建的指针访问成员(属性和函数) * 使用双冒号 ()
从类本身访问静态成员函数,而不将对象作为句柄。[注意:您也可以从具有或不推荐的实例调用静态成员函数].
new
->
::
.
->
评论
->
new
->
className::non_static_member_function()
.
点运算符用于直接成员选择方案。
print(a.b)
在这里,我们正在访问 ,它是对象的直接成员。因此,首先,是一个对象,并且是 的成员(函数/变量等)。b
a
a
b
a
箭头运算符用于间接成员选择方案。
print(a->b)
在这里,我们正在访问哪个是对象的成员,该对象指向 。它是 (*a).b
的简写,所以在这里,它主要是指向对象的指针,并且是该对象的成员。b
a
a
b
双冒号(作用域)运算符用于与命名空间相关的直接成员选择方案。
print(a::b)
在这里,我们正在访问哪个是 class/namespace 的成员。因此,首先,是一个类/命名空间,并且是 的成员(函数/变量等)。b
a
a
b
a
上一个:django 过滤器帮助
下一个:何时使用哪种指针?
评论