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

来源:8-4 运算符重载

Edot

2023-06-26

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

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

图片描述

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

图片描述

打印出的地址如下。

图片描述

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

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

图片描述

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

图片描述

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

图片描述

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

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

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

写回答

2回答

quickzhao

2023-06-27

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

0
2
quickzhao
回复
Edot
不客气,加油。
2023-06-27
共2条回复

Edot

提问者

2023-06-26

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

0
1
quickzhao
嗯,重点要注意这里在重载+运算符时防止临时对象产生的优化。
2023-06-27
共1条回复

重学C++ ,重构你的C++知识体系

一部大片,一段历史,构建C++知识框架的同时重塑你的编程思维

3884 学习 · 1103 问题

查看课程