我正在查看有关成员引用运算符的C ++标准(一元*
解引用运算符,->
成员访问运算符)以及许多其他相关问题:
C++ - Difference between (*). and ->?
ptr->hello(); /* VERSUS */ (*ptr).hello();
C++ pointers difference between * and ->
我看到大多数答案都说p->m
是C ++标准(5.2.5,第2段)定义的(*p).m
的语法糖:
表达式
E1->E2
将转换为等效形式(*(E1)).E2
许多评论还指出,因为operator*
和operator->
在类中是可重载的,所以它们应该统一重载以确保一致的行为。
这些陈述似乎相互矛盾:如果(根据标准)E1->E2
转换为等效形式(*(E1)).E2
,那么重载operator->
的目的是什么(如是否允许标准)?
更简单的说明,标准的这两部分是否存在冲突,还是我误解了标准?
对E1->E2
的{{1}}等价转换是否适用于所有完整类型或仅适用于内置类型?
答案 0 :(得分:5)
从E1 -> E2
到(*(E1)).E2
的转换仅适用于原始指针类型。对于类类型,E1 -> E2
求值为(E1).operator->().E2
,如果operator->
的返回类型本身不是指针类型,则operator->
可能会递归扩展更多operator*
的副本。您可以通过创建支持operator->
但不支持operator->
的类型并尝试在其上使用箭头运算符来查看此内容;您将收到operator ->
未定义的错误。
作为后续工作,以operator *
方式实现->
的方式很常见,其方式使得PointerType ClassType::operator-> () const {
return &**this;
}
的语义与指针的语义相匹配。你经常会看到这样的事情:
&(*(*this)),
此表达式被解释为
*this
含义"获取此对象(*(*this)
),取消引用它(&(*(*this))
),并获取您找到的地址(E1 -> E2
。)。"现在,如果您使用(*(E1)).E2
应该等同于{{1}}的规则,您可以看到最终得到的内容相同。