我正在查看有关成员引用运算符(一元 *
取消引用运算符、->
成员访问运算符)的 C++ 标准以及许多其他相关问题:
C++ - Difference between (*). and ->?
ptr->hello(); /* VERSUS */ (*ptr).hello();
C++ pointers difference between * and ->
我看到大多数答案都指出 p->m
是 C++ 标准定义的 (*p).m
的语法糖(5.2.5,段落2):
The expression
E1->E2
is converted to the equivalent form(*(E1)).E2
很多评论还指出,因为operator*
和operator->
在类中是可重载的,所以应该统一重载以确保一致的行为。
这些陈述似乎相互矛盾:如果(根据标准)E1->E2
转换为等效形式 (*(E1)).E2
,那么重载 operator->
的目的是什么(标准允许)?
更简单地说,标准的这两部分是否有冲突,还是我误解了标准?
E1->E2
到 (*(E1)).E2
的等价转换适用于所有完整类型还是仅适用于内置类型?
最佳答案
从 E1 -> E2
到 (*(E1)).E2
的转换仅适用于原始指针类型。对于类类型,E1 -> E2
的计算结果为 (E1).operator->().E2
,这可能会递归地扩展出更多的 operator 拷贝->
如果 operator->
的返回类型本身不是指针类型。您可以通过创建一个支持 operator*
但不支持 operator->
的类型并尝试在其上使用箭头运算符来看到这一点;你会得到一个错误,提示 operator->
未定义。
作为后续行动,通常根据 operator *
实现 operator ->
,使 ->
具有语义code> 匹配指针的语义。你经常会看到这样的事情:
PointerType ClassType::operator-> () const {
return &**this;
}
这个表达式被解释为
&(*(*this)),
意思是“获取这个对象 (*this
),解引用它 (*(*this)
),然后得到你找到的地址 (& (*(*this))
.)"现在,如果您使用 E1 -> E2
应该等同于 (*(E1)).E2
的规则,您会发现您最终得到了等价的东西。
关于C++ 成员访问/间接运算符等价,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35756466/