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 ++取消引用和使用点运算符与使用箭头运算符之间有区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章

简述指针和引用的区别与使用场景

Rust Deref与自动解引用

如何使用 alsa 库 API 与耳机和扬声器一起使用?

示例:使用消息传递在 Activity 和 Service 之间进行通信

word用endnote导入参考文献,文末的参考文献编号和后边的作者名之间的空格大小怎么调整

Vue中使用Axios拦截器(拦截请求与相应)