C++的箭头操作符

直接上代码

#include <iostream>
#include <string>


class Entity
{
public:
	void Print() const { std::cout << "Hello!" << std::endl; }
};

int main()
{
	Entity e;
	e.Print();

	Entity* ptr = &e;
	Entity& entity = *ptr;
	entity.Print();
	(*ptr).Print();
	ptr->Print();
}

我们可以思考一下为什么entity.Print(); (*ptr).Print(); ptr->Print();都可以正确的调用hello?

在C++中,指针是一个变量,它存储了另一个变量的内存地址。而引用是已存在变量的别名。它们都可以用来访问和操作变量,但是有一些语法和使用上的区别。

在C++中,Entity& entity = *ptr; 这段代码定义了一个对 Entity 类型的引用 entity,并将其初始化为指针 ptr 所指向的对象。这里有几个关键点需要理解:

引用(Reference):在C++中,引用是已存在变量的别名。一旦一个引用被初始化为某个对象,它就不能再被改变为引用另一个对象。引用在语法上表现得就像一个变量,但实际上它并不拥有自己所引用的对象的内存空间。

解引用(Dereferencing)*ptr 是一个解引用操作,它返回指针 ptr 所指向的对象。在这个例子中,ptr 指向 e,所以 *ptr 就是 e

Entity& entity:这定义了一个名为 entity 的引用,该引用指向一个 Entity 类型的对象。

初始化Entity& entity = *ptr; 这行代码将 entity 初始化为 *ptr,即 e。这意味着 entity 现在成为了 e 的一个别名。对 entity 的任何操作都将直接作用在 e 上,因为它们是同一个对象的不同名字。

现在,既然 entity 是 e 的一个引用,你可以通过 entity 来访问 e 的任何公有成员,就像直接通过 e 一样;所以我们可以像前面一样直接用“.”来访问类中的公有成员。因此,对 entity 的任何修改都会反映到 e 上,因为它们是同一个对象。同样地,如果 e 被销毁(例如离开了其作用域),那么对 entity 的任何访问都将是未定义的,因为它们都指向了同一个不再存在的对象。

ptr->Print();

这是使用指针调用其指向对象的成员函数的常见方式。-> 运算符首先解引用指针(即获取指针指向的对象的地址),然后调用该对象的成员函数。所以,ptr->Print(); 实际上是先解引用 ptr 得到 e,然后调用 e 的 Print 方法。

(*ptr).Print();

这里,我们首先使用 * 运算符来解引用 ptr,得到 e 的一个副本(但实际上由于 e 是一个对象而不是基本类型,这里得到的是 e 的引用,但我们可以暂时忽略这个细节)。然后,我们使用 . 运算符来调用 e 的 Print 方法。虽然这里看起来我们好像创建了一个 e 的副本,但实际上因为 Entity 是一个类类型,所以 *ptr 实际上返回的是 e 的引用,而不是副本。因此,这和直接调用 e.Print(); 是等效的。

总结一下:ptr->Print(); 和 (*ptr).Print(); 都是有效的,因为它们都在做同样的事情:先解引用指针 ptr 得到 e,然后调用 e 的 Print 方法。只是语法上稍有不同而已。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值