当前位置: 首页 > news >正文

详解C++赋值操作符重载

1.赋值操作符重载的原因

赋值操作符是一个使用频率最高的操作之一,通常情况下它的意义十分明确,就是将两个同类型的变量的值从一端(右端)传到另一端(左端)。但在以下两种情况下,需要对赋值操作符进行重载。
一是赋值号两边的表达式类型不一样,且无法进行类型转换。
二是需要进行深拷贝。

2. 赋值操作符重载的注意事项

赋值操作符只能通过类的成员函数的形式重载。这就说明了,如果要将用户自定义类型的值传递给基本数据类型的变量,只能通过类型转换机制,而不能利用重载来实现。

当赋值号两边的表达式不一致的时候,可能需要对赋值操作符进行重载,见下面的例子。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#include <iostream>

usingnamespacestd;

classA

{

intnum;

public:

A(){num=0;}

A(inti){num=i;}

voidshow(){

cout<<num<<endl;

}

};

intmain(intargc,char* argv[])

{

A a=5;//符值符号两边的数据类型不一样,这里表示创建新对象

a.show();

A a1;

a1=1;//赋值号两边的数据类型不一样,这是真正的赋值运算

a1.show();

}

程序的输出结果是:

5
1

在语句A a=5中,虽然用到了“=”,但它的语义是构造一个类A的对象a,它等价于语句A a(5),所以该语句与赋值无关。而语句a1=1是一个真正的赋值语句,变量a1的类型是A,而常量1的类型是int,由于可以通过类A的构造函数A(int)将类型int转换成类型A(实际上是以int为参数构造了一个类A的临时对象),然后再完成赋值操作,所以不必再对赋值操作符进行重载。

3.深拷贝情况下对赋值操作符重载

深拷贝是对赋值操作符进行重载的一个因素。那么什么是深拷贝呢?简单的说,深拷贝是在把一个类对象a拷贝到另一个对象b中去时,如果对象a中包含非悬挂指针(野指针),那么要将a的指针所指区域的内容拷贝到b的相应指针所指的区域中去。进行深拷贝时,一般对象a和b有相同的数据类型。如果在进行赋值时发生深拷贝,就一定要对赋值操作符进行重载,否则赋值运算符就会按赋值的常规语义进行(成员变量之间传递数据),而不发生深拷贝。考察如下例子。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

#include <iostream>

usingnamespacestd;

classStudent

{

char* name;

intage;

public:

Student()

{

name=newchar[20];

}

Student(char* n,inta)

{

name=newchar[20];

if(name)strcpy(name,n);

age=a;

}

Student(constStudent& s)

{

name=newchar[20];

*this=s;

}

voidshow()

{

cout<<"The student's name is "<<name;

cout<<" and of age "<<age<<endl;

}

~Student()

{

delete[] name;

}

Student& operator=(constStudent &s)

{

if(name)strcpy(name,s.name);

age=s.age;

return*this;

}

};

intmain()

{

Student s1("张三",18),s4("李四",20);

Student s2;

s1.show();

s2=s4;

s2.show();

Student s3=s1;

s3.show();

return0;

}

程序的输出结果是:

The student's name is 张三 and of age 18
The student's name is 李四 and of age 20
The student's name is 张三 and of age 18

阅读以上程序,注意如下几点。

(1)由于在类Student中,存在指针成员name,所以,当两个Student类成员之间赋值时,必须使用深拷贝。执行s2=s4;语句,就是将s4对象赋值给s2,其中将s4.name字符串的内容拷入s2.name就是对深拷贝的具体体现。

(2)类的拷贝构造函数虽然与赋值操作符并不是一回事,但通常可以在拷贝构造函数中利用赋值操作符重载,以避免对两个对象之间传递数据的重复解释。

(3)上面的程序,直接使用strcpy(name,s.name);实现两个对象的字符串成员的数据传递。这是一种简化的做法,存在很多隐患。比如如果源字符串的长度超过20个字符,此程序会出现运行时错误。解决的办法是根据原字符串的长度,重新分配目的字符串的长度,再次之前还要释放目的字符串的空间。另外,一个对象赋值给自己,也会出现问题,需要进行源对象和目的对象地址的比较,再考虑赋不赋值。

(4)由于深拷贝会涉及到内存的动态分配和释放等一些较为复杂的操作,所以程序员在编写自定义类时要尽量避免深拷贝的出现。例如,在上例中,将成员变量name定义成string name,就可以避免自己编写实现深拷贝的代码。实际的深拷贝工作是由string类来完成,而string类是C++标准库提供的,我们可放心使用。

(5)最赋值操作符进行重载时,通常将操作符函数的返回值定义为赋值左操作数类型的引用。这是为了实现对赋值表达式的求值,还有一个目的就是为了实现链式操作。


http://www.jsqmd.com/news/713239/

相关文章:

  • 用ESP32C3+Arduino IDE,5分钟搞定MiniMax大模型对话机器人(附完整代码)
  • 如何使用PostCSS优化字体加载性能:提升网页加载速度的完整指南
  • 7个元数据字段掌控AI代理行为:Semantic Kernel配置实战指南
  • 2026年3月咖啡机定制厂家推荐,咖啡机/加热型破壁机/传统榨汁机/智能豆浆机/柔音破壁机,咖啡机制造厂家哪家好 - 品牌推荐师
  • 盘点2026年广东好用的铝合金阳光房品牌,排名情况如何 - 工业设备
  • Tao-8k模拟技术面试官:针对Java八股文的智能提问与反馈
  • 终极Total War模组开发指南:用RPFM快速打造专业级游戏模组
  • 如何用Django REST Framework实现监控即代码:可编程监控配置管理完整指南
  • 如何彻底解决C盘空间不足问题?Windows Cleaner终极指南
  • 告别盲调!手把手教你用CANoe的CAPL脚本玩转XCP协议(附连接/断开/状态查询实战代码)
  • 国内管理咨询公司推荐,筛选咨询公司有哪些实用技巧 - 工业设备
  • Adobe-GenP 3.0终极指南:5分钟免费解锁Adobe全系列软件
  • 5分钟掌握哔哩下载姬:你的B站视频下载神器
  • Free-NTFS-for-Mac:突破macOS NTFS读写限制的技术解决方案
  • 计算机视觉统一模型:理解与生成的融合架构解析
  • 终极Pydantic数据验证指南:如何在Apache Kafka流处理中实现无缝集成
  • AAEON EPIC-TGH7单板计算机:Xeon性能与工业应用解析
  • 如何用200行代码打造你的第一个编译器:The Super Tiny Compiler完全指南
  • 2026年公园菊花展哪家好,纳境园林高性价比菊花展览受青睐 - 工业设备
  • 从CTF靶场到实战:手把手教你用Python脚本破解5种RSA经典变种题
  • AMD Ryzen调试神器:SMUDebugTool完全使用指南
  • 3分钟极速安装:彻底解决GitHub访问卡顿的终极浏览器插件方案
  • nli-MiniLM2-L6-H768一文详解:Cross-Encoder在垂直领域微调的可行性路径
  • 微信立减金怎么回收?我的操作经验 - 抖抖收
  • 终极解密Python执行黑盒:帧对象如何管理你的代码运行状态
  • 5分钟快速掌握:完全本地的视频字幕提取终极解决方案
  • Hitboxer终极指南:免费开源SOCD清洁工具如何彻底解决你的游戏操作冲突
  • 强化学习奖励函数设计与DERL框架解析
  • 终极指南:3款Font Awesome对比度检测工具让界面瞬间专业
  • 2026数字档案建设优选:国内五大专业档案系统服务商实力解析 - 速递信息