热门标签 | 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;


推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • switch语句的一些用法及注意事项
    本文介绍了使用switch语句时的一些用法和注意事项,包括如何实现"fall through"、default语句的作用、在case语句中定义变量时可能出现的问题以及解决方法。同时也提到了C#严格控制switch分支不允许贯穿的规定。通过本文的介绍,读者可以更好地理解和使用switch语句。 ... [详细]
  • 加密世界下一个主流叙事领域:L2、跨链桥、GameFi等
    本文介绍了加密世界下一个主流叙事的七个潜力领域,包括L2、跨链桥、GameFi等。L2作为以太坊的二层解决方案,在过去一年取得了巨大成功,跨链桥和互操作性是多链Web3中最重要的因素。去中心化的数据存储领域也具有巨大潜力,未来云存储市场有望达到1500亿美元。DAO和社交代币将成为购买和控制现实世界资产的重要方式,而GameFi作为数字资产在高收入游戏中的应用有望推动数字资产走向主流。衍生品市场也在不断发展壮大。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
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社区 版权所有