热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

类与对象(3)

目录1.操作符重载1.1赋值运算符重载1.2操作符重载1.3!操作符重载1.4操作符1.8前置和后置1.9前置-

目录

1. 操作符重载

1.1 赋值运算符重载

1.2  ==操作符重载

1.3  !=操作符重载

1.4 <操作符重载

1.5  <&#61; 操作符重载

1.6 > 操作符

 1.7 >&#61;操作符

1.8 前置&#43;&#43;和后置&#43;&#43;

1.9 前置--和后置--

2. 编写一个Date类




1. 操作符重载

C&#43;&#43;为了增强代码的可读性引入了运算符重载&#xff0c;运算符重载是具有特殊函数名的函数&#xff0c;也具有其返回值类 型&#xff0c;函数名字以及参数列表&#xff0c;其返回值类型与参数列表与普通的函数类似。

函数名字为&#xff1a;关键字operator后面接需要重载的运算符符号

函数原型&#xff1a;返回值类型 operator操作符(参数列表)

这里我们统一使用Date类来进行以下操作

class Date
{
public://进行操作符的重载//...
private:int _year;int _month;int _day;
};

注意&#xff1a;

1. 不能通过连接其他符号来创建新的操作符&#xff1a;比如operator ^ 、operator&#64;等&#xff0c;只能重载已存在的操作符。

2. .* ::(作用域访问符) sizeof()?:(三目操作符) .(点)以上5个运算符不能重载。


1.1 赋值运算符重载

注意&#xff1a;

1. 赋值运算符只能作为类的成员函数

赋值运算符在类中不显式实现时&#xff0c;编译器会生成一份默认的&#xff0c;此时用户在类外再将赋值运算符重载&#xff0c;就和编译器生成的默认赋值运算符冲突了&#xff0c;故赋值运算符只能重载成成员函数

2. 赋值操作符不等同与拷贝构造函数

这里是调用赋值操作符还是拷贝构造呢&#xff1f;

 我们发现最后进入了拷贝构造函数里面。

说明当对象初始化的时候使用赋值操作符调用的并不是重载后的操作符&#xff0c;而是调用拷贝构造函数&#xff0c;

只有对象已经被初始化了以后再次调用赋值操作符&#xff0c;才会使用重载后的操作符。

那我们如何实现呢&#xff1f;

Date& operator&#61;(const Date& d) {if (this !&#61; &d) {_year &#61; d._year;_month &#61; d._month;_day &#61; d._day;return *this;}}

 这里我们也使用了上一节学习的参数带引用和返回值带引用。

返回值带引用就算出了函数也是存在的&#xff0c;因此返回别名不会担心非法访问的问题。

参数带引用则是为了避免无限递归问题。


1.2  &#61;&#61;操作符重载

在内置类型中的&#61;&#61;就是将双方中的值进行比较&#xff0c;而在自定义类型中也同样如此&#xff0c;只不过自定义类型不能像内置类型一样直接比较&#xff0c;因为自定义类型中存在着内置类型和自定义类型&#xff0c;在使用&#61;&#61;时&#xff0c;就需要对其进行重载。

bool operator&#61;&#61;(const Date& d) {return _year &#61;&#61; d._year && _month &#61;&#61; d._month && _day &#61;&#61; d._day;}

1.3  !&#61;操作符重载

!&#61;操作符&#xff0c;当双方不相等时返回true&#xff0c;当双方相等时返回false&#xff0c;这不就是&#61;&#61;操作符的相反值吗

bool operator !&#61; (const Date& d) {return !(*this &#61;&#61; d);}

这里我们就是利用了函数的复用性原理&#xff0c;极大地减小了我们的代码量并且使得代码更加清晰。


1.4 <操作符重载

同理还是当自定义类型中所有的成员变量都<返回true&#xff0c;否则返回false

bool operator <(const Date& d) {if (_year

1.5  <&#61; 操作符重载

只要满足小于或者等于任意一个就返回true&#xff0c;否则返回false

bool operator <&#61; (const Date& d) {return (*this

1.6 > 操作符

>的反义词就是<&#61;,同样利用复用性

bool operator>(const Date& d) {return !(*this<&#61;d);
}

 1.7 >&#61;操作符

我们可以使用>&#61;的反义词是<来写&#xff0c;也可以利用>和&#61;满足一个的条件来写

bool operator >&#61; (const Date& d) {//return (*this>d)||(*this&#61;&#61;d);return !(*this

1.8 前置&#43;&#43;和后置&#43;&#43;

在对&#43;&#43;操作符进行重载时&#xff0c;形式为&#xff1a;operator&#43;&#43;()&#xff0c;那我们是如何区分什么时候使用前置&#43;&#43;&#xff0c;什么时候使用后置&#43;&#43;呢&#xff1f;

对于前置&#43;&#43;不写入参数&#xff0c;形式为&#xff1a;operator&#43;&#43;()

对于后置&#43;&#43;写入参数&#xff0c;形式为&#xff1a;operator&#43;&#43;(int i)

对于参数的类型是规定好的&#xff0c;我们只需要照做即可&#xff0c;无须思考太多。

我们首先来看前置&#43;&#43;

Date& operator&#43;&#43;() {*this &#43;&#61; 1;return *this;}

前置&#43;&#43;我们只需要记住先&#43;&#43;再使用

后置&#43;&#43;

Date operator&#43;&#43;(int i) {Date ret(*this);*this &#43;&#61; 1;return ret;}

先创建一个对象来拷贝当前的数值&#xff0c;然后再&#43;&#43;&#xff0c;返回创建的临时对象。


1.9 前置--和后置--

与1.8同理&#xff0c;附上代码

// 前置--Date& operator&#43;&#43;() {*this -&#61; 1;return *this;}// 后置--Date operator--(int i) {Date ret(*this);*this -&#61; 1;return ret;}

如果返回值能带有&最好&#xff0c;因为可以少一个拷贝的步骤&#xff0c;增加速率&#xff0c;因此能使用带&返回就使用&。


2. 编写一个Date类

那学习了这么多的操作符重载和之前相关的知识&#xff0c;我们就可以写出一个完成的类

class Date
{public://判断闰年bool judge(int year) {if (year % 400 &#61;&#61; 0 || (year % 4 &#61;&#61; 0 && year % 100 !&#61; 0)) {return true;}return false;}// 获取某年某月的天数int GetMonthDay(int year, int month) {int MonthDayArrays[13] &#61; { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (month &#61;&#61; 2 && judge(year)) {return 29;}return MonthDayArrays[month];}// 全缺省的构造函数Date(int year &#61; 1900, int month &#61; 1, int day &#61; 1) {if (year >&#61; 1 && month >&#61; 1 && month <&#61; 12 &&day >&#61; 1 && day <&#61; GetMonthDay(year, month)) {_year &#61; year;_month &#61; month;_day &#61; day;}}void print() {cout <<_year <<"-"<<_month <<"-"<<_day < d2.operator&#61;(&d2, d3)Date& operator&#61;(const Date& d) {if (this !&#61; &d) {_year &#61; d._year;_month &#61; d._month;_day &#61; d._day;return *this;}}// 析构函数//~Date();// 日期&#43;&#61;天数Date& operator&#43;&#61;(int day) {if (day <0) {return *this -&#61; -day;}_day &#43;&#61; day;while (_day > GetMonthDay(_year, _month)) {_day -&#61; GetMonthDay(_year, _month);_month&#43;&#43;;if (_month &#61;&#61; 13) {_year&#43;&#43;;_month &#61; 1;}}return *this;}// 日期&#43;天数Date operator&#43;(int day) const { Date ret(*this);ret &#43;&#61; day;return ret;}// 日期-天数Date operator-(int day) const {Date ret(*this);ret -&#61; day;return ret;}// 日期-&#61;天数Date& operator-&#61;(int day) {if (day <0) {return *this &#43;&#61; -day;}_day -&#61; day;while (_day <&#61; 0) {--_month;if (_month &#61;&#61; 0) {_year--;_month &#61; 12;}_day &#43;&#61; GetMonthDay(_year, _month);}return *this;}// >运算符重载bool operator>(const Date& d) {if (_year > d._year || (_year &#61;&#61; d._year && _month > d._month) ||(_year &#61;&#61; d._year && _month &#61;&#61; d._month && _day > d._day)) {return true;}return false;}// &#61;&#61;运算符重载bool operator&#61;&#61;(const Date& d) {return _year &#61;&#61; d._year && _month &#61;&#61; d._month && _day &#61;&#61; d._day;}// >&#61;运算符重载inline bool operator >&#61; (const Date& d) {return !(*this d);}// !&#61;运算符重载bool operator !&#61; (const Date& d) {return !(*this &#61;&#61; d);}// 日期-日期 返回天数int operator-(const Date& d) {int temp &#61; 0;Date max &#61; d;Date min &#61; *this;int flag &#61; -1;if (*this>d){max &#61; *this;min &#61; d;flag &#61; 1;}for (int i &#61; min._year; i private:int _year;int _month;int _day;};


完成一次小练习&#xff01;&#xff01;


推荐阅读
  • 本文总结了 #define 在 C/C++ 编程中的多种用途和技巧,包括定义常量、函数、宏以及条件编译等,并提供了详细的示例和注意事项。 ... [详细]
  • 本文详细探讨了PHP中使用const和define定义常量的方法及其差异。了解这些区别有助于开发者根据具体需求选择合适的方式定义常量。 ... [详细]
  • Gradle 是 Android Studio 中默认的构建工具,了解其基本配置对于开发效率的提升至关重要。本文将详细介绍如何在 Gradle 中定义和使用共享变量,以确保项目的一致性和可维护性。 ... [详细]
  • 本文探讨了Linux环境下线程私有数据(Thread-Specific Data, TSD)的概念及其重要性,介绍了如何通过TSD技术避免多线程间全局变量冲突的问题,并提供了具体的实现方法和示例代码。 ... [详细]
  • 本文档旨在提供C语言的基础知识概述,涵盖常量、变量、数据类型、控制结构及函数定义等内容。特别强调了常量的不同类型及其在程序中的应用,以及如何正确声明和使用函数。 ... [详细]
  • 题面:P3178[HAOI2015]树上操作好像其他人都嫌这道题太容易了懒得讲,好吧那我讲。题解:第一个操作和第二个操作本质上是一样的&# ... [详细]
  • 使用 Babylon.js 实现地球模型与切片地图交互(第三部分)
    本文继续探讨在上一章节中构建的地球模型基础上,如何通过自定义的 `CameraEarthWheelControl` 类来实现更精细的地图缩放控制。我们将深入解析该类的实现细节,并展示其在实际项目中的应用。 ... [详细]
  • 本文详细介绍了Socket在Linux内核中的实现机制,包括基本的Socket结构、协议操作集以及不同协议下的具体实现。通过这些内容,读者可以更好地理解Socket的工作原理。 ... [详细]
  • 本文探讨了如何选择一个合适的序列化版本ID(serialVersionUID),包括使用生成器还是简单的整数,以及在不同情况下应如何处理序列化版本ID。 ... [详细]
  • 如何使用Maven将依赖插件一并打包进JAR文件
    本文详细介绍了在使用Maven构建项目时,如何将所需的依赖插件一同打包进最终的JAR文件中,以避免手动部署依赖库的麻烦。 ... [详细]
  • STM32代码编写STM32端不需要写关于连接MQTT服务器的代码,连接的工作交给ESP8266来做,STM32只需要通过串口接收和发送数据,间接的与服务器交互。串口三配置串口一已 ... [详细]
  • 本文详细探讨了在Windows 98环境下安装Apache 1.3.9、JServ、GNUJSP 1.0、JDK 1.2.2及JSDK 2.0后遇到的中文显示问题,并提供了多种有效的解决方案。 ... [详细]
  • egg实现登录鉴权(七):权限管理
    权限管理包含三部分:访问页面的权限,操作功能的权限和获取数据权限。页面权限:登录用户所属角色的可访问页面的权限功能权限:登录用户所属角色的可访问页面的操作权限数据权限:登录用户所属 ... [详细]
  • SSE图像算法优化系列三:超高速导向滤波实现过程纪要(欢迎挑战)
    自从何凯明提出导向滤波后,因为其算法的简单性和有效性,该算法得到了广泛的应用,以至于新版的matlab都将其作为标准自带的函数之一了&#x ... [详细]
  • 本文详细介绍了 Node.js 中 OS 模块的 arch 方法,包括其功能、语法、参数以及返回值,并提供了具体的使用示例。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有