C ++取消引用和使用点运算符与使用箭头运算符之间有区别[重复]
Posted
技术标签:
【中文标题】C ++取消引用和使用点运算符与使用箭头运算符之间有区别[重复]【英文标题】:C++ is there a difference between dereferencing and using dot operator, vs using the arrow operator [duplicate] 【发布时间】:2021-11-01 19:58:02 【问题描述】:假设我有以下变量:
MyObject* obj = ...;
如果这个对象有字段foo
,有两种访问方式:
obj->foo
(*obj).foo
使用一种方法与另一种方法有什么不同。还是第一种方法只是第二种方法的语法糖?
我在想也许第一个可能会导致对象的复制构造函数被调用,因为它现在持有该值。
【问题讨论】:
是的,我很确定这只是语法糖。至少在您的情况下是这样;当涉及重载运算符时,行为可能会有所不同。 “我在想也许第一个可能会导致对象的复制构造函数被调用,因为它现在持有该值。”你为什么这么认为? 对于重载的operator->
,->
具有“向下钻取”属性,在该属性中递归应用,直到结果对象为指针。 q.v. ***.com/a/10460730/4641116
@AlessandroTeruzzi 按值传递会导致调用复制构造函数,所以我在想,也许取消引用是按值将对象传递给取消引用它的代码段。只是一个想法,我认为情况并非如此。
【参考方案1】:
obj
是指针时没有区别。
如果obj
是某个类的对象,obj->foo
将调用operator->()
,(*obj).foo
将调用operator*()
。从理论上讲,您可以重载这些以执行完全不同的行为,但这将是一个设计非常糟糕的类。
【讨论】:
【参考方案2】:根据§7.6.1.5 ¶2 of the ISO C++20 standard,表达式obj->foo
被转换为(*obj).foo
。所以它只是语法糖。两者是等价的。
我在想也许第一个可能会导致对象的复制构造函数被调用,因为它现在持有该值。
不会调用构造函数,因为没有创建新对象。
【讨论】:
【参考方案3】:第一种方法只是第二种方法的语法糖吗?
是的。
我在想也许第一个可能会导致对象的复制构造函数被调用
没有。
从技术上讲,区别在于 operator.
不能为类重载,而 operator->
可以重载。运算符 ->
和 *
应该被重载,以使 it->foo
和 (*it).foo
保持等效,尽管从技术上讲,该语言并未强制这样做。
【讨论】:
以上是关于C ++取消引用和使用点运算符与使用箭头运算符之间有区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章
示例:使用消息传递在 Activity 和 Service 之间进行通信