我正在查看有关成员引用运算符(一元*解除引用运算符,->成员访问器运算符)以及许多其他相关问题的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的规则,那么您可以看到最终得到了等同的东西。

07-26 09:28
查看更多