请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

有关赋值运算符及其重载的问题

老师好,我做了一个实验,对于实验现象还不能彻底理解。

首先仿照课堂内容定义了一个复数类Complex,并对其"+"运算符进行重载,如下。在重载函数中打印了tmp变量的地址。

图片描述

此时,还没有对"="运算符进行重载,按照下面两种形式进行赋值,并将左值的地址打印出来。

图片描述

打印出的地址如下。

图片描述

可以看到,两种不同的赋值方式会产生不同的效果。

而后对"="运算符进行重载,重载函数如下。

图片描述

如下可以看到,第一种赋值会调用重载函数,而第二种不会(第一种赋值中的等于号变颜色了)。

图片描述

运行,打印出的地址如下。

图片描述

可以看到,两种方法产生的效果仍然不同。

推测:是不是因为两种赋值操作其实是不同的,虽然都用了"="这个符号,第一种是真正的赋值,第二种是“定义”了一个变量,故产生此结果?

其他疑问:栈区变量tmp为何在离开函数作用域后仍然有效?是认为其被引用了所以就有效吗?还是说此处产生这种现象仅仅是编译器的一种优化?

正在回答

2回答

这里不建议你采用取地址符号的方式来简单判断一些现象,如果你用不同的编译器编译得到的结果会不一样,因为有些编译器可能会有自己的优化策略。这里最根本的区别是result_1已经初始化,而result_2还没有初始化。所以函数流程上result_1会直接触发+运算符和=运算符的行为,你这里虽没有重载=,但是C++会有一个系统默认的浅拷贝的=重载;而result_2则会触发+运算符和拷贝构造。至于你说的栈区变量离开函数作用域后仍有效则可能是触发了编译器的RVO优化策略和move语义。我不清楚你具体使用的编译器和版本,所以没法细致的跟踪你编译器的行为。你可以根据我提供的这些点和编译器的编译选项来判断具体的行为。

0 回复 有任何疑惑可以回复我~
  • 提问者 Edot #1
    谢谢老师!
    回复 有任何疑惑可以回复我~ 2023-06-27 09:49:40
  • quickzhao 回复 提问者 Edot #2
    不客气,加油。
    回复 有任何疑惑可以回复我~ 2023-06-27 09:54:06
提问者 Edot 2023-06-26 23:03:44

看了8-5拷贝构造这节课,我基本懂了(* ̄3 ̄)╭

0 回复 有任何疑惑可以回复我~
  • 嗯,重点要注意这里在重载+运算符时防止临时对象产生的优化。
    回复 有任何疑惑可以回复我~ 2023-06-27 09:24:37
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信