C++成员访问/间接运算符等效性
C++ member access/indirection operator equivalence
我正在查看有关成员引用运算符(一元*
取消引用运算符,->
成员访问器运算符)的C++标准以及许多其他相关问题:
C++ - (*)之间的区别。 和 ->?
ptr->hello();/* VERSUS */(*ptr).hello();
C++ * 和 -> 之间的指针差异
我看到大多数答案都说p->m
是C++标准(5.2.5,第2段)定义的(*p).m
的句法糖:
表达式
E1->E2
将转换为等效形式(*(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 ->
。你经常看到这样的事情:
PointerType ClassType::operator-> () const {
return &**this;
}
此表达式解释为
&(*(*this)),
意思是"获取此对象(*this
),取消引用它(*(*this)
),并获取您找到的内容的地址(&(*(*this))
.)。现在,如果您使用规则 E1 -> E2
应该等效于 (*(E1)).E2
,您可以看到您最终会得到等效的东西。
- 在运算符重载定义中使用成员函数(const错误)
- 三向比较运算符成员与非成员实现
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 消除好友和成员二进制运算符的歧义
- 不允许运算符 const 参数调用 const 成员函数
- 有人可以用"显式运算符 const GUID_t&() const"来解释成员函数的函数吗?
- 为什么重载运算符<<打印特征类成员会导致段错误?
- 运算符重载作为成员函数
- 如何测试成员相等运算符?
- 如何处理运算符=中的常量成员?
- 将方法委托给成员的重写运算符>
- C++ 20 中的运算符 == 和 <=> 应该作为成员还是自由函数实现?
- 清除具有已删除赋值运算符的成员的类实例
- 运行时多态性 - 箭头运算符访问了错误的成员?
- 如何正确返回带有成员变量的重载运算符++?
- 使用 delete [] 运算符取消分配类中数据成员的内存
- 模板的赋值运算符(成员函数)实现的正确语法
- 模板类友元运算符成员函数
- 我只能有const重载的运算符成员函数
- 由算术运算符成员函数修改的动态数组的复制构造函数