【问题标题】:C++ member access/indirection operator equivalenceC++ 成员访问/间接运算符等价
【发布时间】:2016-06-15 20:26:24
【问题描述】:

我正在查看有关成员引用运算符(一元 * 取消引用运算符、-> 成员访问运算符)以及许多其他相关问题的 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

许多 cmets 还指出,由于 operator* 和 operator-> 在类中是可重载的,因此应统一重载它们以确保行为一致。

这些陈述似乎相互矛盾:如果(根据标准)E1->E2 转换为等效形式(*(E1)).E2,那么重载operator-> 的目的是什么(标准允许) ?

简单地说,标准的这两个部分是否存在冲突,还是我误解了标准?
E1->E2 到 (*(E1)).E2 的等价转换适用于所有完整类型还是仅适用于内置类型?

【问题讨论】:

  • 参见第 5 条的第 3 点,“第 5 条定义了运算符在应用于未重载的类型时的效果。”

标签: c++ pointers language-lawyer


【解决方案1】:

从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 的规则,你可以看到你最终得到了等价的东西。

【讨论】:

  • 这是一个很好的解释!在等效表达式转换之前,我从未意识到对原始指针的解析。该示例是一个非常有用的说明。
猜你喜欢
  • 2012-02-05
  • 1970-01-01
  • 2011-06-11
  • 2012-01-13
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
  • 1970-01-01
  • 2022-10-18
相关资源
最近更新 更多