既然*
运算符返回对对象的引用,而且->
基本上是(*a).b
的简写,那么C++为什么要定义一个单独的重载呢?在我看来,您似乎希望不惜一切代价保持*
和->
同步,以避免出现奇怪的错误,但*运算符也已经可以定义->
了。
编辑:为了澄清,我的推理是,如果->
的实现只是(*a).b
。如果我们只是重载了*
运算符,并将->
基本上像对待(*a).b
形式的宏一样处理,那么重载的*
将应用于新表达式,我们将获得免费的重载->
最初,C++没有对您定义的运算符或是否以逻辑对称的方式定义运算符设置任何规则。您可以选择只实现一个或多个比较运算符,尽管后来的标准试图在某种程度上规范化这一点。
有几种方法可以利用它:
- 您可能希望阻止
*
用于获取内部对象,并获取其地址
是的,->
获取内部对象,但它不会使其处于可访问状态,必须调用一个成员。
实际上,->
提供了比*
更好的OOP。
好的,是的,正如HBC所指出的,对象调用者可以直接调用方法operator->()
并获得对象,但我认为这在任何代码审查中都是明显的代码气味。我的意思是,你可以重新解释_cast<gt;如果我们沿着这条路径前进,对象字节就会进入指针。
当然,是的,如果您要实现*
,那么您也可以实现->
,但不一定反之亦然。
- 您可能要做的另一件事是实现
*
,为您提供一个原始的数据块或简单的结构,然后您可以传输或存储它,但->
为您提供了一个与数据配对的操纵器对象,因此为一个简单的结构添加了一些对象丰富性。在这种情况下,您不能简单地直接添加丰富性,可能是因为数据是由旧的C库提供的
您甚至可以让简单的blob实现一些紧凑的c样式嵌套结构多态性,而->
为您提供了一个等效的智能操纵器。
以这种方式,CCD_;视图";基于您的数据。这可能会让人感到困惑,或者这可能是为一段哑数据提供对象功能的明显方式,而这些数据可能仍然需要作为哑数据进行访问。所有这些工具都提供给API定义者明智地使用。
简单的答案是-用C++你会发现很多次-为什么不呢?
您可以看到其他运算符也是如此:operator+
、operator-
一元运算符和二进制运算符;operator<
、operator<=
、operator==
、operator>=
、operator>
、operator!=
和许多其他-如果在标准意义上使用它们,它们是可以相互推导的。然而,有可能推翻它们。
现在,重写的原因可能因项目而异:有时,您希望实现EDSL,而一元*
的含义可能与->
完全不同;有时,您希望优化架构的最后一部分;有时,您正在移植某人从例如Java复制粘贴的代码,并希望在->
中进行特殊检查,而这些检查在*
中是不需要的;你的理由可能各不相同。
然而,C++并没有强制执行一种特定的"好"方法。事实上,Bjarne自己(在C++布达佩斯会议上(说过,他希望保持C++的多样性,并允许多种编程风格和范式。所以语言本身并没有限制你。