Series article description
This series of C++ related articles is only for the author’s study notes, and I will use my own understanding to record the study! The C++ learning series will be divided into three stages: basics, STL, and advanced data structures and algorithms . The relevant key contents are as follows:
- Basics : Classes and Objects (involving the three major features of C++, etc.);
- STL : Learn to use the STL related libraries provided by C++ ;
- High-order data structures and algorithms : Manually implement your own STL library and design and implement high-order data structures , such as B-tree, B+ tree, red-black tree, etc.
Study set:
Article directory
- Series article description
- Preface
- 1. C++ arithmetic (assignment) operator overloading
- 2. C++ auto-increment and decrement operator overloading
- related articles
Preface
- The basic learning of classes has reached a certain stage, so the content that the author will share with you in the recent articles is: "
运算符重载小专题
"! Currently updated:关系运算符的重载(点击跳转)
,输入输出运算符重载(点击跳转)
, solved the problem of comparison and input and output of custom types/objects! - In this article, the author will share with you
自定义类型 / 对象
the calculation problem of ! That is:自增自减运算符重载及算术运算符重载
.
1. C++ arithmetic (assignment) operator overloading
1. Description
This article will
+、-、+=、-=
take as an example to design and implement arithmetic (assignment) operator overloading! [Note: In the previous description of operator overloading, it was mentioned that operator overloading cannot change its own meaning! 】
2. += / -= operator overloading [take the Date calendar class as an example]
符号含义
:
+=
: Addition and assignment operator, assigns the result of adding the right operand to the left operand to the left operand!-=
: Subtraction AND assignment operator, assigns the result of subtracting the right operand from the left operand to the left operand
For our Date date class, the generally provided interfaces include: Calculate the date problem of adding or subtracting how many days after the current date!
At this time, calculation situations such as: 2023-6-16 += or + 15 days will appear! Obviously it is impossible to perform calculations using the original operators! (As shown below)
2.1 Design ideas
Therefore, we need to overload our operators!
由于 + 或 - 可以基于 += 或 -= 来实现
, so the author gives priority to implementing it+= / -= 的重载
!
Implement design ideas:
参数问题
: Obviously you need to pass a number of days for recursive operation. The value does not need to be changed, so it can be modified with const.日期迭代计算问题
: Due to the date change involved, we需要考虑的每个月的天数问题
! And可能出现闰年二月的情形
!
2.2 Solution: Leap Year Problem (Introduction to Calculation Rules and Origin)
About: leap year problem!
判断闰年的方式(1582年后的计算准则):该年可以被 400 整除 或 概念可以被 4 整除但不能被 100 整除,如:1900年不是闰年!
Regarding the origin of leap years: (The above calculation rules for leap years are those after 1582!)
- The leap rules of the Gregorian calendar since 1582:
- Ordinary leap year: If the Gregorian calendar year is a multiple of 4 and not a multiple of 100, it is a leap year (such as 2004, 2020, etc. are leap years).
- Century leap year: The Gregorian calendar year is a hundred, and it must be a multiple of 400 to be a leap year (for example, 1900 is not a leap year, but 2000 is a leap year).
- The convention before 1582: there is a leap year every four years; if A (positive number) in year A AD can be divided by 4, then it is a leap year; if B (positive number) in year B BC divides 4 and the remainder is 1, then it is a leap year. It's also a leap year.
Leap year judgment function implementation (as follows):
- Parameters: year
- Return value: yes/no
/* 闰年判断 */
bool IsLeapYear(int year) {
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}
2.3 Days in the month issue
In order to facilitate calculation, the author designed the acquisition of the number of days in the month as a function!
Design ideas:
- Parameters: year, month
- Return value: int type (number of days)
- Special processing: February is set to 28 days by default. If a leap year is encountered, the return value is +1;
优化处理:由于获取月份天数可能使用频率较高,建议使用数组存储数据(设计如下:注意注释解释),并设定为静态数组!(避免每次调用函数新建数组的性能开销!)。
The code is implemented as follows:
/* 获取月份天数 */
int GetMonthDay(int year, int month) {
/* 设置为静态数组提升效率 */
/* 数组大小设置为 13 ,即为了直接使用 days[month] 访问到数据 */
static int days[13] = {
0,31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2 && IsLeapYear(year)) {
return days[month] + 1;
}
return days[month];
}
2.4 Overloading design and implementation of += or -= operator
设计思路(注意点):
- The basic idea: always add/decrease the number of days to calculate the date. During the process, pay attention to judging the month change and year change!
- Parameters: Extrapolate the number of days passed.
返回值:日期的引用!
其他细节见注释!
+= 运算符重载(实现如下)
/* += 赋值运算符重载 */
Date& Date::operator += (const int day) {
_day += day; /* 直接递增天数 */
while (_day > GetMonthDay(_year, _month)) {
/* 日期“合法性”判断 */
/* 若:天数大于本月的固定天数,则 天数 - 本月天数,并将月份 + 1 */
_day -= GetMonthDay(_year, _month); /* 天数更跌 */
_month += 1; /* 月份更迭 */
if (_month == 13) {
/* 年份更迭 */
_month = 1;
_year++;
}
}
return *this;
}
-= 运算符重载(实现如下)
Date& Date::operator -= (const int day) {
_day -= day;
while (_day < 1) {
/* 判断天数合法性 */
if (_month == 1) {
/* 特殊点:年份更迭 */
_month = 13; /* 注意此处:13,为的是后续统一的月份更迭计算 */
_year--;
}
_day += GetMonthDay(_year, _month - 1);
_month--;
}
return *this;
}
2.5 Test legend results
3. + or - operator overloading
Combined with what was mentioned in the previous article to improve code reusability, you can directly use the existing += or -= to implement the key points of the + or - operator!
3.1 Overloading design, implementation and testing of + operator
+ 运算符重载(实现如下,注意注释提示)
注意返回值:不是引用!
/*
在该函数中,不会去修改 Date 对象本身,
而是返回一个新的对象,
函数外部可以赋值给原对象或新对象!
*/
Date Date::operator+(const int day) const
{
// Date ret(*this); /* 拷贝构造 */
Date ret = *this;
ret += day;
return ret;
}
3.2 - Operator overloading design, implementation and testing
+ 运算符重载(实现如下,注意注释提示)
注意返回值:不是引用!
/*
在该函数中,不会去修改 Date 对象本身,
而是返回一个新的对象,
函数外部可以赋值给原对象或新对象!
*/
Date Date::operator-(const int day) const
{
// Date ret(*this); /* 拷贝构造 */
Date ret = *this;
ret -= day;
return ret;
}
4. About *, /, *=, /= overload design and implementation
- Regarding the design and implementation of overloading of *, /, *=, /=, according to the previous content, just follow the example!
2. C++ auto-increment and decrement operator overloading
1.Basic understanding
In C/C++, we can use
++ / --
to perform increment and decrement operations on the data variables we define! These two operators can be described as a nightmare for newcomers to learn, especially in the final examination papers of college students, which have no practical significance in the evaluation of combinations of increment and decrement operators. [Basic usage is shown in the picture below! 】
In previous studies, you may have heard more or less:
前置自增自减 效率高于 后置自增自减
. [Of course, there must be almost no difference under current compilers, and it has already been optimized]
It is known that
自增自减运算符分为:前置 和 后置
, the main difference is:
- Prepositioning means: giving priority to its own operation before participating in other operations;
- The postposition is: first participate in other operations, and then perform its own operation!
2. Implementation of overloading of auto-increment and auto-decrement operators
Front-end and rear-end
++ / --
In actual use, we write the difference between front-end and rear-end, but what should we do when overloading?
函数写法:使用函数重载!
重载函数的区分方式
: Use a parameter to distinguish !方案:前置使用无参形式,后置使用含参形式
[ Note: After actual implementation, we do not need to display the parameter passed in the post-implementation process! The compiler will automatically identify the distinguishing parameters of the auto-increment and auto-decrement operator overloading]函数返回值:对象本身(引用返回)
The design code is as follows (note reuse of code):
2.1 Prefixed ++ or – operator overloading implementation
前置 ++ ,即先 +1 再返回!
前置 -- ,即先 -1 再返回!
/* 前置 ++ */
Date& Date::operator++()
{
return *(this + 1);
}
/* 前置 -- */
Date& Date::operator--()
{
return *(this - 1);
}
2.2 Postfix ++ or – operator overloading implementation
后置 ++ ,即先返回,再运算!
(With the aid of: temporary objects)后置 -- ,即先返回,再运算!
(With the aid of: temporary objects)
/* 后置 ++ */
Date& Date::operator++(int)
{
Date ret(*this);
*this += 1;
return ret;
}
/* 后置 -- */
Date& Date::operator--(int)
{
Date ret(*this);
*this += 1;
return ret;
}
2.3 Test result legend
related articles
1. [C++ Basics Chapter: 21]: friend Friends asked four questions: What is a friend? Friend class? Friend function? When to use friends?
2. [C++ Basics: 22]: Const objects and const member functions/methods of classes and common problems involving const in classes!
3. [C++ Basics: 23]: [Important Template] Design and implementation of relational operator overloading: [ > , < , >= , <= , != , == ] overloading [taking the Date time class as an example]