我正在查看有关成员引用运算符(一元*
解除引用运算符,->
成员访问器运算符)以及许多其他相关问题的C++标准:
C++ - Difference between (*). and ->?
ptr->hello(); /* VERSUS */ (*ptr).hello();
C++ pointers difference between * and ->
我看到大多数答案都表明p->m
是(*p).m
的语法糖,如C++标准(5.2.5,第2段)所定义:
许多评论还指出,由于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 *
,使->
的语义与指针的语义匹配。您经常看到这样的事情:
PointerType ClassType::operator-> () const {
return &**this;
}
该表达式被解释为
&(*(*this)),
意思是“获取该对象(
*this
),对其进行取消引用(*(*this)
),并获取找到内容的地址(&(*(*this))
)。”现在,如果您使用E1 -> E2
应该等于(*(E1)).E2
的规则,那么您可以看到最终得到了等同的东西。