C++赋值运算符重载【C++赋值运算符重载】
- 赋值运算符重载
- 说明
- 语法
- 特性
- 自实现存在的问题
- 重析构
- 内存泄漏
- 自赋值
- 解决
- 小结
赋值运算符重载
说明
赋值运算符重载是用一个已经存在的对象,给另一个已经存在的对象赋值,两个对象均已创建结束后,发生赋值行为。
语法
格式固定:
类名
{ 类名 & operator=(const 类名 & 源对象) {//拷贝体return *this; }
}
class A
{ A & operator=(const A & another) { //函数体 return *this; }
};
特性
代码演示:
#include <iostream>
using namespace std;struct Data
{public:Data(int y = 2016, int m = 6, int d = 6):year(y), month(m), day(d){}void dis(){cout << " year " << year << " month " << month << " day " << day << endl;}
private:int year;int month;int day;
};int main()
{Data d(2018, 8, 8); d.dis();Data d2(2019, 9, 9);d2 = d;d2.dis();return 0;
}
运行结果:
可以看到并没有自己写赋值运算符重载,但是确实赋值成功了,并且正确赋值。
进行说明:
系统默认提供的赋值运算符重载。也是一种浅赋值行为。
理解:
拷贝构造器和赋值运算符重载的区别,拷贝构造器是原来不存在直接进行构造一份,赋值运算符重载是本来就有两份,然后拿第一份的将第二份覆盖。
如果对象中不存在堆内存空间,此时系统默认提供的赋值运算符重载可以满足需求。如果对象中含有堆上的内存空间则需要自实现完成深拷贝。
格式语法固定。
一旦自实现,系统默认提供的赋值运算符重载将不存在。
如果自实现了但是里面没有内容,那么就不能实现赋值运算符重载:
#include <iostream>
using namespace std;struct Data
{public:Data(int y = 2016, int m = 6, int d = 6):year(y), month(m), day(d), space(new char[1024]){}Data & operator = (const Data& another){}void dis(){cout << " year " << year << " month " << month << " day " << day << endl;}
private:int year;int month;int day;char* space;
};int main()
{Data d(2018, 8, 8); d.dis();Data d2(2019, 9, 9);d2 = d;d2.dis();return 0;
}
运行结果为:
可以看到赋值运算符没有重载成功。
自实现运算符重载:
#include <iostream>
using namespace std;struct Data
{public:Data(int y = 2016, int m = 6, int d = 6):year(y), month(m), day(d), space(new char[1024]){}Data & operator = (const Data& another){this->year = another.year;this->month = another.month;this->day = another.day;return *this;}void dis(){cout << " year " << year << " month " << month << " day " << day << endl;}
private:int year;int month;int day;char* space;
};int main()
{Data d(2018, 8, 8); d.dis();Data d2(2019, 9, 9);d2 = d;d2.dis();return 0;
}
运行结果:
上面实例中实现的赋值运算符重载和系统默认提供的赋值运算符重载实现的结果是一样的。
为什么在运算符重里面加入了return * this
:
给出main函数中的代码,其他代码不变:
int main()
{Data d(2018, 8, 8); d.dis();Data d2(2019, 9, 9);d2 = d;d2.dis();//使用返回this指针Data d3;d3 = d2 = d; //与下面一行代码实现意义完全不相同d3.operator=(d2.operator=(d));return 0;
}
理解:d
赋值给d2
,整个表达式返回了d2
,然后d2
作为参数进行传递,将d2
赋值给d3
,整个表达式又返回d3
。
自实现存在的问题
重析构
在释放内存的时候就会出现重析构问题。
内存泄漏
解决:先把自己之前的内存进行释放,然后进行深拷贝。
自赋值
自赋值意思就是说当出现自己赋值给自己的时候,那么原来的内存空间被释放了,但是原来的内存空间里面还是自己本身,如果释放之后就无法进行赋值运算符重载,所以我们在自实现的是时候就要解决这个问题。
解决
代码实现:
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <iostream>
using namespace std;struct Data
{public:Data(int y = 2016, int m = 6, int d = 6):year(y), month(m), day(d), space(new char[1024]){}Data& operator = (const Data& another)//赋值运算符重载{if (this == &another) //解决自赋值的问题return *this; //实现链式表达else{delete[]this->space; //解决内存泄漏的问题space = new char[strlen(another.space) + 1];strcpy(space, another.space);}year = another.year;month = another.month;day = another.day;return *this;}~Data() //析构器{cout << "~~~~~~~~" << this << endl; //指向当前对象的指针delete[]space;}void dis(){cout << " year " << year << " month "<< month << " day " << day << endl;}
private:int year;int month;int day;char* space;
};int main()
{Data d(2018, 8, 8);d.dis();Data d2(2019, 9, 9);d2 = d;d2.dis();return 0;
}
上面自实现代码就解决了这三个问题。
运行结果:
接下来进行说明在:
Data & operator = (const Data & another)
进行传递的时候参数使用 const
的作用就是 another
里面的内容肯定不会修改。
那么 Data & operator = (const Data & another)
最前面没有引用,所以可以返回this
指针的内容,如果给最前面也加上const
。
const Data & operator = (const Data & another)
我们可以看到如果在返回引用的时候没有使用const
,返回之后可以被赋值。如果不想被赋值就在返回类型前面加上const
。
例如:(d3 = d2) = d;
如果前面有const
那么表达式不可以被赋值。
小结
C++赋值运算符重载【C++赋值运算符重载】相关推荐
- C++——重载运算符和重载函数
重载运算符和重载函数 C++ 中的函数重载 C++ 中的运算符重载 C++ 一元运算符重载 C++ 二元运算符重载 C++ 关系运算符重载 C++ 输入/输出运算符重载 C++ 赋值运算符重载 C++ ...
- 重载函数和重载运算符
C++允许在同一个作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但他们的参数列表和定义(实现)不相 ...
- 运算符重载——递增运算符重载
目录: 运算符重载--算术运算符重载 运算符重载--递增运算符重载 运算符重载--左移运算符重载 运算符重载--赋值运算符重载 应用场景: class MyInteger { public:MyInt ...
- 运算符重载——左移运算符重载
目录: 运算符重载--算术运算符重载 运算符重载--递增运算符重载 运算符重载--左移运算符重载 运算符重载--赋值运算符重载 应用场景: 可以输出自定义的数据类型信息 Person p(" ...
- 运算符重载——算术运算符重载
目录: 运算符重载--算术运算符重载 运算符重载--递增运算符重载 运算符重载--左移运算符重载 运算符重载--赋值运算符重载 应用场景: Person p1(100);// p1有100元 Pers ...
- 面向对象编程(三):重载运算符和重载函数
C++ 重载运算符和重载函数 C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是 ...
- C++ | C++ 重载运算符和重载函数
文章目录 C++ | C++ 重载运算符和重载函数 C++ 重载运算符和重载函数 C++ 中的函数重载 实例1: C++ 中的运算符重载 实例2: 可重载运算符/不可重载运算符 运算符重载实例 运算符 ...
- 函数重载、运算符重载
函数重载.运算符重载 1.函数重载 2.运算符重载 1.函数重载 1.1函数重载的定义 函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个 ...
- C++ 重载运算符和重载函数(一)
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不 ...
- C++ : 构造函数,拷贝构造函数,移动构造函数,拷贝赋值运算符,移动赋值运算符应用场景
构造函数,拷贝构造函数,移动构造函数,拷贝赋值运算符,移动赋值运算符应用场景 #include <iostream> using namespace std;class Construct ...
最新文章
- 假如AI也会diss人类,他们会这样.....
- 内核同步机制——自旋锁
- const char*, char const*, char*const 的区别
- 1.6 去除字符串中的空格(trim())
- java全局变量怎么定义_怎么在java中创建一个自定义的collector
- Android之解决NestedScrollView嵌套RecyclerView部分手机返回到这个页面Recyclerview顶部,而不是页面NestedScrollView顶部
- 如何使用Docker轻松集成OnlyOffice和NextCloud--快速搭建私有云办公系统/私有云盘/私有OfficeOnline
- linux eth_p_ip,linux数据链路访问之ETH_P_ALL等等
- 你敢信?FBI 的190万条恐怖分子监控名单竟无密码保护且不慎遭暴露
- git ignore 某行
- 启动Hadoop时遇到Name or service not knownstname 错误
- 练习题︱基于今日头条开源数据(二)——两款Apriori算法实践
- cocos2dx lua 打印和保存日志
- java 算法递归案例_JAVA 几个递归算法实例
- 比起高性能计算,高端存储才更亟待国产化
- ST语言入门(维修电工1)
- Github+Facebook=?这家公司有望让程序猿的头秃得慢一点
- matlab 图形对称,求任意轴对称图形的核心的Matlab代码实现
- Reactive 反应式编程
- 将dwg文件转为shp文件