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

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

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

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

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

#include <iostream>
using namespace std;class A
{int num;
public:A(){num=0;}A(int i){num=i;}void show(){cout<<num<<endl;}
};int main(int argc, 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有相同的数据类型。如果在进行赋值时发生深拷贝,就一定要对赋值操作符进行重载,否则赋值运算符就会按赋值的常规语义进行(成员变量之间传递数据),而不发生深拷贝。考察如下例子。

#include <iostream>
using namespace std;class Student
{char* name;int age;
public:Student(){name=new char[20];}Student(char* n, int a){name=new char[20];if(name) strcpy(name,n);age=a;}Student(const Student& s){name=new char[20];*this=s;}void show(){cout<<"The student's name is "<<name;cout<<" and of age "<<age<<endl;}~Student(){delete[] name;}Student& operator=(const Student &s){if(name) strcpy(name,s.name);age=s.age;return *this;}
};int main()
{Student s1("张三",18),s4("李四",20);Student s2;s1.show();s2=s4;s2.show();Student s3=s1;s3.show();return 0;
}

程序的输出结果是:

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

C++赋值操作符重载相关推荐

  1. C++中的赋值操作符重载

    文章目录 1 C++中的赋值操作符重载 1.1 赋值操作符重载 1 C++中的赋值操作符重载 1.1 赋值操作符重载 关于赋值操作符: 编译器为每个类默认重载了赋值操作符. 默认的赋值操作符仅完成浅拷 ...

  2. 拷贝构造函数、析构函数、赋值操作符重载、取地址操作符重载和const修饰的取地址操作符重载...

    2019独角兽企业重金招聘Python工程师标准>>> 在我们学习C++的过程中,我们难免会遇到类,在类中有6个默认的函数,它们分别为:构造函数.拷贝构造函数.析构函数.赋值操作符重 ...

  3. 类与对象:类的6个默认成员函数: 构造函数、析构函数、拷贝构造函数、赋值操作符重载、默认拷贝构造与赋值运算符重载的问题、const成员函数、 取地址及const取地址操作符重载

    1.类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类.任何一个类在我们不写的情况下,都会自动生成下面6个默认成员函数. 构造函数 析构函数 拷贝构造函数 赋值操作符重载 const成员函数 ...

  4. C++:重载操作符 赋值操作符重载需要注意的问题

    一.操作符重载 1.什么是操作符重载 就是把一些操作符通过关键字operator,组装成一个函数,关键字operator后面接需要重载的操作符符号 2.为什么需要重载操作符? (1)简单.方便,比起封 ...

  5. const , 拷贝构造函数,赋值操作符重载

    int a1 = 0;const int b1 = 1;int* p0; // 普通指针const int* p1; // 可修改所指对象,但不可修改所指对象的值int const* p2; // 可 ...

  6. 拷贝构造,操作符重载

     拷贝构造 #include <iostream> #include <string.h> using namespace std; class mystring { pu ...

  7. C/C++ 之 操作符重载

    1.成员函数重载操作符:除".","*","::","?:"外其他操作符都可重载 (1) a.双目操作符声明格式: cl ...

  8. c++操作符重载,拷贝构造函数和友…

    操作符重载 把c++的操作符在自己的新函数中重新实现就是操作符重载. 可以在类里面以成员函数的方式重载某个操作符,也可以在某个名字空间中重载操作符. ------------------------- ...

  9. Kotlin 操作符重载详解

    本文主要内容 算术操作符重载 二元操作符重载 复合赋值操作符重载 一元操作符重载 比较操作符重载 集合相关的操作符重载 索引操作符重载 索引操作符重载Kotlin集合中的应用 in 操作符重载 区间操 ...

最新文章

  1. java office 集成开发_Office文件格式突变,促使Java和Office更完美集成
  2. 外卖平台涉嫌大数据杀熟,处理不能“自说自话”
  3. 用于传递列表作为选项的argparse选项
  4. java迷宫队列实现_Creator 迷宫生成: DFS 与 BFS 算法实现
  5. ABAP--关于ABAP流程处理的一些命令的说明(stop,exit,return,check,reject)
  6. ARM公司的Cortex-M0概况介绍
  7. KVO(NSKeyValueObserving)、KVC(NSKeyValueCoding)作用浅谈
  8. 论文赏析【EMNLP19】语言模型效果不好?也许你可以给它添加一点句法信息
  9. QEMU/KVM libvirt X710 PCI passthrough DPDK 网络性能测试
  10. HTML+CSS+JS做一个简易音乐播放器
  11. 硬件入门之PCB设计注意事项
  12. Kali Linux 使用记录
  13. 宽带信号的DOA估计学习笔记(四):空间分辨率
  14. c语言自动填表chrome网页,Form Filler:自动填写表单
  15. CSS高手布局:让footer完美处于网页下方
  16. Linux服务器Ldap安装及ldaps配置完整流程
  17. css使用定义动画anima,CSS Transform和动画
  18. myeclipse2017下载安装与破解详细教程
  19. 一个生成密保卡的程序
  20. Python中list、tupe、dic、set的使用小记

热门文章

  1. 推特称攻击者利用其 API 匹配用户名和电话号码
  2. FortiGuard 被曝使用硬编码密钥和 XOR 加密通信
  3. 成都睿铂 | 落差区域无人机倾斜摄影航线的规划要点
  4. 云计算网络基础第一天
  5. Mysql经常使用函数汇总
  6. sccm2012 客户端推送安装故障解决一例
  7. ffmpeg和SDL教程 04:创建线程
  8. NIS企业级应用案例-统一Linux和Windows身份验证(二)
  9. NEWS - InstallShield 2013发布
  10. 当VS2005卸载不干净时