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

[C++ 从入门到精通] 12.重载运算符、赋值运算符重载、析构函数

  • 📢博客主页:https://loewen.blog.csdn.net
  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
  • 📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉
  • 📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨

文章预览:

      • 一. 重载运算符
      • 二. 赋值运算符重载
      • 三. 析构函数


一. 重载运算符

1、运算符

  • 算术运算符:+、-、*、/、%
  • 赋值运算符:=
  • 关系运算符:>、<、>=、<=、==、!=
  • 逻辑运算符:&&,||;等

2、重载运算符:就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

🐾 特性:运算符重载本质上就是一个函数

  • 在函数体内实现想要的功能,当用到该运算符时,编译器会自动调用这个函数;
  • 有返回类型和参数列表;

也就是说,运算符重载是通过函数实现的,它本质上是函数重载。

💐 语法:函数的名字由关键字operator及其紧跟的运算符组成 ,比如:重载+运算符 ==>operator+ 重载=号运算 ==>operator=

🌸 其他

有一些运算符的重载系统会自动生成,比如赋值运算符=,而有些运算符的重载系统不会自动生成,需要我们手动定义,比如关系运算符==

比如定义类的两个对象:

class Time
{
public:Time();int Hour;int Minute;int Second;
};
int main()
{Time myTime;Time myTime2;if(myTime == myTime2);  //比较对象A和对象B,不可以,比较运算符“==”缺省的情况下,系统不会自动生成,//并且系统不知道你要在什么样的条件下,才能判断两个对象是否相等,//所以需要自己对比较运算符“==”来重新定义,用于两个对象的比较。myTime = myTime2;       //将对象B赋值给对象A,可以,赋值运算符“=”缺省的情况下, 系统会自动生成。return 0;
}    

那么如何重新定义比较运算符==,使其可以判断两个对象是否相等呢?

这里的重新定义即比较运算符重载,我们可以规定某些规则来判断两个对象是否相等,比如当它的两个成员变量Hour之间的值相等时,我们可以判断两个对象相等之类的。


二. 赋值运算符重载

前面我们有提到过,如果赋值运算符“=”缺省的情况下,系统会自动生成一个默认的赋值运算符重载(函数)实现对象的赋值,将对象myTime2的数据成员逐一拷贝到对象myTime中。

虽然默认的赋值运算符重载(函数)能够实现很多拷贝,但是有很多时候它是不行的,这时需要对赋值运算符进行重载(重新定义)。

✨ 格式:T & operator=(const T&)

  • 参数类型:const T&,传递引用可以提高传参效率;
    const修饰:防止赋值的时候,参数值被修改;
  • 返回*this返回自身对象的引用,即等号=左边对象(下文myTime6)的地址
class Time
{
public:Time();int Hour;int Minute;int Second;Time(const Time &tmptime,int a = 5);Time & operator=(const Time&);   //若禁止赋值运算符重载的时候,将其声明为private即可
};
Time::Time():Hour(11), Minute(58), Second(49)
{std::cout << "调用了Time::Time()构造区数" << std::endl;
}Time::Time(const Time &tmptime, int a)
{std::cout << "调用了Time::Time(Time &taptime, int a)拷贝构造区数" << std::endl;
}//赋值运算符重载
Time & Time::operator=(const Time& tmp)
{Hour = tmp.Hour;Minute = tmp.Minute;Second = tmp.Second;std::cout << "调用了Time & Time::operator=(const Time& tmp)赋值运算符重载" << std::endl;return *this; //返回自身对象的引用
}
int main()
{Time myTime;               //调用构造函数Time myTime5 = { myTime }; //调用拷贝构造函数Time myTime6;              //调用默认构造函数(不带参数)myTime6 = myTime5;         //这个是赋值运算符,即没调用构造函数,也没调用拷贝构造函数//但系统会调用一个赋值运算符重载return 0;
}

在这里插入图片描述

可以看到,在最后执行myTime6 = myTime5时,调用了我们自己定义的赋值运算符重载,目的是可以更精确的控制类Time的赋值操作。

其中,在执行myTime6 = myTime5时,会调用Time & Time::operator=(const Time& tmp)赋值运算符函数。即:将myTime5的地址赋值给参数tmp,在函数内部完成一系列赋值操作后,再将对象的引用返回给myTime6。从而完成myTime5myTime6的赋值操作。


三. 析构函数

🐶 定义:析构函数」是特殊的类成员函数,「析构函数」 与 「构造函数」的作用正好相反,「构造函数」是对象创建的时候自动调用的,而 「析构函数」就是对象在销毁的时候自动调用的的。

🐵 格式: ~类名()

🐭 特性:

  • 默认生成性:同于「构造函数」,如果不显式的定义「析构函数」,编译器会生成一个默认的函数体为空的「析构函数」;
  • 唯一性:不同于「构造函数」可以有多个重载函数(名同、参不同),「析构函数」只有一个,并且因为不接收任何参数,所以不能被重载;
class Time
{
public:Time();~Time();
};
Time::~Time()
{std::cout << "调用了Time::~Time()析构函数" << std::endl;
}
int main()
{Time myTime;              Time myTime1 = { myTime }; system("pause");return 0;
}

在这里插入图片描述

因为在main函数体内创建了两个局部类对象,所以在main函数结束时(return之前)会自动调用两次析构函数(若为全局对象,则会在程序运行结束时调用析构函数)。

🐷 new对象和delete对象(配对使用):

Time *ptime = new Time();    //new动态创建类对象,这时系统会调用类Time的构造函数delete ptime;                //delete手动释放内存,这时系统会调用类Time的析构函数

有的人可能会觉得,若Time *ptime = new Time()出现在某个函数中时,认为其是个局部指针,会在函数运行结束之后ptime的内存被自动释放掉。这种想法是错误的,记住只要出现new,一定要delete手动释放其创建的内存。

总结: 对于用new动态创建的对象,一定要在程序停止运行的某个时刻,手动delete释放掉其内存,否则就会造成内存泄漏。


态度"ABC"理论的三个维度,即情感(Affective)、行为(Behavioral)和认知(Cognitive)

相关文章:

  • 应用软件安全编程--24不要使用硬编码密匙
  • 如何通过cpolar内网穿透工具实现远程访问本地postgreSQL
  • ExcelBDD PHP Guideline
  • vim模式用法总结
  • 基于RK3588全高端智能终端机器人主板
  • 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法
  • MATLAB 嵌套switch语句||MATLAB while循环
  • C#,数值计算——插值和外推,分段线性插值(Linear_interp)的计算方法与源程序
  • MySQL索引:作用、类型、设计原则、优化策略与常见陷阱
  • python实现炫酷的屏幕保护程序
  • Three.js相机模拟
  • 数据结构 并查集
  • 9 HDFS架构剖析
  • 【Linux】线程互斥
  • 记GitLab服务器迁移后SSH访问无法生效的问题解决过程
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • 【知识碎片】第三方登录弹窗效果
  • CSS实用技巧
  • java2019面试题北京
  • JavaScript的使用你知道几种?(上)
  • js面向对象
  • nodejs实现webservice问题总结
  • Python 反序列化安全问题(二)
  • Python利用正则抓取网页内容保存到本地
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • Sublime Text 2/3 绑定Eclipse快捷键
  • Terraform入门 - 1. 安装Terraform
  • 从零开始学习部署
  • 前嗅ForeSpider采集配置界面介绍
  • 温故知新之javascript面向对象
  • 协程
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 一份游戏开发学习路线
  • ​水经微图Web1.5.0版即将上线
  • ​虚拟化系列介绍(十)
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • $(function(){})与(function($){....})(jQuery)的区别
  • (4)STL算法之比较
  • (pytorch进阶之路)扩散概率模型
  • (多级缓存)多级缓存
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (区间dp) (经典例题) 石子合并
  • (新)网络工程师考点串讲与真题详解
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • ./和../以及/和~之间的区别
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .a文件和.so文件
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .NET CORE Aws S3 使用
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .net 调用php,php 调用.net com组件 --
  • .net 开发怎么实现前后端分离_前后端分离:分离式开发和一体式发布