当前位置:网站首页>类与对象(3)
类与对象(3)
2022-06-11 21:36:00 【爱学代码的学生】
目录
1. 操作符重载
C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类 型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)
这里我们统一使用Date类来进行以下操作
class Date
{
public:
//进行操作符的重载
//...
private:
int _year;
int _month;
int _day;
};注意:
1. 不能通过连接其他符号来创建新的操作符:比如operator ^ 、[email protected]等,只能重载已存在的操作符。
2. .* 、::(作用域访问符) 、sizeof() 、?:(三目操作符) 、.(点)以上5个运算符不能重载。
1.1 赋值运算符重载
注意:
1. 赋值运算符只能作为类的成员函数
赋值运算符在类中不显式实现时,编译器会生成一份默认的,此时用户在类外再将赋值运算符重载,就和编译器生成的默认赋值运算符冲突了,故赋值运算符只能重载成成员函数。
2. 赋值操作符不等同与拷贝构造函数

这里是调用赋值操作符还是拷贝构造呢?

我们发现最后进入了拷贝构造函数里面。
说明当对象初始化的时候使用赋值操作符调用的并不是重载后的操作符,而是调用拷贝构造函数,
只有对象已经被初始化了以后再次调用赋值操作符,才会使用重载后的操作符。
那我们如何实现呢?
Date& operator=(const Date& d) {
if (this != &d) {
_year = d._year;
_month = d._month;
_day = d._day;
return *this;
}
}这里我们也使用了上一节学习的参数带引用和返回值带引用。
返回值带引用就算出了函数也是存在的,因此返回别名不会担心非法访问的问题。
参数带引用则是为了避免无限递归问题。
1.2 ==操作符重载
在内置类型中的==就是将双方中的值进行比较,而在自定义类型中也同样如此,只不过自定义类型不能像内置类型一样直接比较,因为自定义类型中存在着内置类型和自定义类型,在使用==时,就需要对其进行重载。
bool operator==(const Date& d) {
return _year == d._year && _month == d._month && _day == d._day;
}1.3 !=操作符重载
!=操作符,当双方不相等时返回true,当双方相等时返回false,这不就是==操作符的相反值吗
bool operator != (const Date& d) {
return !(*this == d);
}这里我们就是利用了函数的复用性原理,极大地减小了我们的代码量并且使得代码更加清晰。
1.4 < 操作符重载
同理还是当自定义类型中所有的成员变量都<返回true,否则返回false
bool operator < (const Date& d) {
if (_year < d._year || (_year == d._year && _month < d._month) ||
(_year == d._year && _month == d._month && _day < d._day)) {
return true;
}
return false;
}1.5 <= 操作符重载
只要满足小于或者等于任意一个就返回true,否则返回false
bool operator <= (const Date& d) {
return (*this<d)||(*this==d)
}1.6 > 操作符
>的反义词就是<=,同样利用复用性
bool operator>(const Date& d) {
return !(*this<=d);
}1.7 >=操作符
我们可以使用>=的反义词是<来写,也可以利用>和=满足一个的条件来写
bool operator >= (const Date& d) {
//return (*this>d)||(*this==d);
return !(*this < d);
}1.8 前置++和后置++
在对++操作符进行重载时,形式为:operator++(),那我们是如何区分什么时候使用前置++,什么时候使用后置++呢?
对于前置++不写入参数,形式为:operator++()
对于后置++写入参数,形式为:operator++(int i)
对于参数的类型是规定好的,我们只需要照做即可,无须思考太多。
我们首先来看前置++
Date& operator++() {
*this += 1;
return *this;
}前置++我们只需要记住先++再使用
后置++
Date operator++(int i) {
Date ret(*this);
*this += 1;
return ret;
}先创建一个对象来拷贝当前的数值,然后再++,返回创建的临时对象。
1.9 前置--和后置--
与1.8同理,附上代码
// 前置--
Date& operator++() {
*this -= 1;
return *this;
}
// 后置--
Date operator--(int i) {
Date ret(*this);
*this -= 1;
return ret;
}
如果返回值能带有&最好,因为可以少一个拷贝的步骤,增加速率,因此能使用带&返回就使用&。
2. 编写一个Date类
那学习了这么多的操作符重载和之前相关的知识,我们就可以写出一个完成的类
class Date
{
public:
//判断闰年
bool judge(int year) {
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
return true;
}
return false;
}
// 获取某年某月的天数
int GetMonthDay(int year, int month) {
int MonthDayArrays[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2 && judge(year)) {
return 29;
}
return MonthDayArrays[month];
}
// 全缺省的构造函数
Date(int year = 1900, int month = 1, int day = 1) {
if (year >= 1 && month >= 1 && month <= 12 &&
day >= 1 && day <= GetMonthDay(year, month)) {
_year = year;
_month = month;
_day = day;
}
}
void print() {
cout << _year <<"-"<< _month << "-"<<_day << endl;
}
// 拷贝构造函数
// d2(d1)
Date(const Date& d) {
_year = d._year;
_month = d._month;
_day = d._day;
}
// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
Date& operator=(const Date& d) {
if (this != &d) {
_year = d._year;
_month = d._month;
_day = d._day;
return *this;
}
}
// 析构函数
//~Date();
// 日期+=天数
Date& operator+=(int day) {
if (day < 0) {
return *this -= -day;
}
_day += day;
while (_day > GetMonthDay(_year, _month)) {
_day -= GetMonthDay(_year, _month);
_month++;
if (_month == 13) {
_year++;
_month = 1;
}
}
return *this;
}
// 日期+天数
Date operator+(int day) const {
Date ret(*this);
ret += day;
return ret;
}
// 日期-天数
Date operator-(int day) const {
Date ret(*this);
ret -= day;
return ret;
}
// 日期-=天数
Date& operator-=(int day) {
if (day < 0) {
return *this += -day;
}
_day -= day;
while (_day <= 0) {
--_month;
if (_month == 0) {
_year--;
_month = 12;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
// >运算符重载
bool operator>(const Date& d) {
if (_year > d._year || (_year == d._year && _month > d._month) ||
(_year == d._year && _month == d._month && _day > d._day)) {
return true;
}
return false;
}
// ==运算符重载
bool operator==(const Date& d) {
return _year == d._year && _month == d._month && _day == d._day;
}
// >=运算符重载
inline bool operator >= (const Date& d) {
return !(*this < d);
}
// <运算符重载
bool operator < (const Date& d) {
if (_year < d._year || (_year == d._year && _month < d._month) ||
(_year == d._year && _month == d._month && _day < d._day)) {
return true;
}
return false;
}
// <=运算符重载
bool operator <= (const Date& d) {
return !(*this>d);
}
// !=运算符重载
bool operator != (const Date& d) {
return !(*this == d);
}
// 日期-日期 返回天数
int operator-(const Date& d) {
int temp = 0;
Date max = d;
Date min = *this;
int flag = -1;
if (*this>d)
{
max = *this;
min = d;
flag = 1;
}
for (int i = min._year; i < max._year; i++) {
temp += judge(i) ? 366 : 365;
}
for (int i = 1; i < max._month; i++) {
temp += GetMonthDay(d._year, i);
}
for (int i = 1; i < min._month; i++) {
temp -= GetMonthDay(_year, i);
}
temp += max._day - min._day;
return temp*flag;
}
private:
int _year;
int _month;
int _day;
};
完成一次小练习!!
边栏推荐
- JVM | runtime data area; Program counter (PC register);
- bzoj3188 Upit
- 如何使用 SAP Kyma 控制台手动发送 SAP Commerce Cloud Mock 应用暴露的事件
- [Part 14] source code analysis and application details of completionservice class [key]
- Iros 2021 | new idea of laser vision fusion? Lidar intensity diagram +vpr
- 12 golden rules of growth
- 焕新升级 | 创新,从云商店开始
- select _ Lazy loading
- Common file functions
- EndnoteX9简介及基本教程使用说明
猜你喜欢
![[v2.1] automatic update system based on motion step API (repair bug, increase completion display, support disconnection reconnection and data compensation)](/img/73/2ec957d58616d692e571a70826787f.jpg)
[v2.1] automatic update system based on motion step API (repair bug, increase completion display, support disconnection reconnection and data compensation)

Answer fans' questions | count the number and frequency of letters in the text

Leetcode-98- validate binary search tree

Flutter implements the JD address selection component

JVM|运行时数据区;程序计数器(PC寄存器);
![BZOJ3189 : [Coci2011] Slika](/img/46/c3aa54b7b3e7dfba75a7413dfd5b68.png)
BZOJ3189 : [Coci2011] Slika

Syntax of SQL

数据库每日一题---第9天:销售员

Jenkins+allure integrated report construction

LeetCode-76-最小覆盖子串
随机推荐
Deploy SAP ui5 applications to the sap BTP kyma operating environment step by step
zypper命令使用示例
LeetCode-32-最长有效括号
如何使用 SAP Kyma 控制台手动发送 SAP Commerce Cloud Mock 应用暴露的事件
Syntax of SQL
Redis data type (string)
Codeworks round 744 (Div. 3) problem solving Report
Leetcode 797. All possible paths
Leetcode-76- minimum covering substring
【历史上的今天】6 月 11 日:蒙特卡罗方法的共同发明者出生;谷歌推出 Google 地球;谷歌收购 Waze
【 C Advanced language】 Integer Storage in Memory
JVM class loader; Parental delegation mechanism
Leetcode-110-balanced binary tree
Educational Codeforces Round 114 (Rated for Div. 2) D
八、BOM - 章节课后练习题及答案
Master of a famous school has been working hard for 5 years. AI has no paper. How can the tutor free range?
Using the sap ui5 cli command line tool to build and run SAP ui5 applications
js对返回的数据的各种数据类型进行非空判断。
How to manually send events exposed by SAP commerce cloud mock application using SAP kyma console
Website online customer service system Gofly source code development log - 2 Develop command line applications