目录
5.赋值运算符重载
5.1 运算符重载
5.2 赋值运算符重载
1. 赋值运算符重载格式
2. 赋值运算符只能重载成类的成员函数不能重载成全局函数
3. 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。
5.3 前置++和后置++重载
6.日期类的实现
1. 不能通过连接其他符号来创建新的操作符:比如operator@2.重载操作符必须有一个类类型参数3.用于内置类型的运算符,其含义不能改变,例如:内置的整型+ ,不 能改变其含义4.作为类成员函数重载时,其形参看起来比操作数数目少1 ,因为成员函数的第一个参数为隐藏的this5 .* :: sizeof ?: . 注意以上 5 个运算符不能重载。这个经常在笔试选择题中出现。
// 全局的operator==
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
//private:
int _year;
int _month;
int _day;
};
// 这里会发现运算符重载成全局的就需要成员变量是公有的,那么问题来了,封装性如何保证?
bool operator==(const Date& d1, const Date& d2)
{
return d1._year == d2._year
&& d1._month == d2._month
&& d1._day == d2._day;
}
void Test ()
{
Date d1(2018, 9, 26);
Date d2(2018, 9, 27);
cout<<(d1 == d2)<
这时候就可以像下面一样,将函数写入类的内部即可解决。
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
// bool operator==(Date* this, const Date& d2)
// 这里需要注意的是,左操作数是this(函数内部隐藏),指向调用函数的对象
bool operator==(const Date & d2)
{
return _year == d2._year
&& _month == d2._month
&& _day == d2._day;
}
private:
int _year;
int _month;
int _day;
};
参数类型: const T& ,传递引用可以提高传参效率返回值类型: T& ,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值检测是否自己给自己赋值返回*this :要复合连续赋值的含义
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
Date& operator=(const Date& d)
{
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
private:
int _year;
int _month;
int _day;
};
如下代码即会报错:
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
int _year;
int _month;
int _day;
};
// 赋值运算符重载成全局函数,注意重载成全局函数时没有this指针了,需要给两个参数
Date& operator=(Date& left, const Date& right)
{
if (&left != &right)
{
left._year = right._year;
left._month = right._month;
left._day = right._day;
}
return left;
}
// 编译失败:
// error C2801: “operator =”必须是非静态成员
class Time
{
public:
Time()
{
_hour = 1;
_minute = 1;
_second = 1;
}
Time& operator=(const Time& t)
{
if (this != &t)
{
_hour = t._hour;
_minute = t._minute;
_second = t._second;
}
return *this;
}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
private:
// 基本类型(内置类型)
int _year = 1970;
int _month = 1;
int _day = 1;
// 自定义类型
Time _t;
};
int main()
{
Date d1;
Date d2;
d1 = d2;
return 0;
}
// 这里会发现下面的程序会崩溃掉 这里就需要深拷贝去解决。
typedef int DataType;
class Stack
{
public:
Stack(size_t capacity = 10)
{
_array = (DataType*)malloc(capacity * sizeof(DataType));
if (nullptr == _array)
{
perror("malloc申请空间失败");
return;
}
_size = 0;
_capacity = capacity;
}
void Push(const DataType& data)
{
// CheckCapacity();
_array[_size] = data;
_size++;
}
~Stack()
{
if (_array)
{
free(_array);
_array = nullptr;
_capacity = 0;
_size = 0;
}
}
private:
DataType* _array;
size_t _size;
size_t _capacity;
};
int main()
{
Stack s1;
s1.Push(1);
s1.Push(2);
s1.Push(3);
s1.Push(4);
Stack s2;
s2 = s1;
return 0;
}
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
// 前置++:返回+1之后的结果
// 注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率
Date& operator++()
{
_day += 1;
return *this;
}
// 后置++:
// 前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载
// C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器自动传递
// 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this + 1
// 而temp是临时对象,因此只能以值的方式返回,不能返回引用
Date operator++(int)
{
Date temp(*this);
_day += 1;
return temp;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d;
Date d1(2022, 1, 13);
d = d1++; // d: 2022,1,13 d1:2022,1,14
d = ++d1; // d: 2022,1,15 d1:2022,1,15
return 0;
}
Date.h:
//Date.h
#pragma once
#include
#include
using namespace std;
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1);
bool operator<(const Date& d);
bool operator<=(const Date& d);
bool operator>(const Date& d);
bool operator>=(const Date& d);
bool operator==(const Date& d);
bool operator!=(const Date& d);
// d1 + 100
Date& operator+=(int day);
Date operator+(int day);
// d1 - 100
Date operator-(int day);
Date& operator-=(int day);
// ++d1
Date& operator++();
// 特殊处理:解决语法逻辑不自洽,自相矛盾的问题
// d1++
// 为了跟前置++区分,强行增加一个int形参,够成重载区分
Date operator++(int);
//Date operator--(int);
//Date& operator--();
// d1 - d2
int operator-(const Date& d);
// 本质就是inline
int GetMonthDay(int year, int month)
{
assert(month > 0 && month < 13);
static int monthDays[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
// 365 自转 公转 365 5+h
// 366
if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
{
return 29;
}
return monthDays[month];
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
Date.cpp:
//Date.cpp
#include"Date.h"
// 全缺省的构造函数
Date::Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
bool Date::operator<(const Date& d)
{
if (_year < d._year)
{
return true;
}
else if (_year == d._year)
{
if (_month < d._month)
{
return true;
}
else if (_month == d._month)
{
if (_day < d._day)
{
return true;
}
}
}
return false;
}
bool Date::operator<=(const Date& d)
{
return (*this < d) || (*this == d);
}
bool Date::operator>(const Date& d)
{
return !(*this <= d);
}
bool Date::operator>=(const Date& d)
{
return !(*this < d);
}
bool Date::operator==(const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
bool Date::operator!=(const Date& d)
{
return _year != d._year
|| _month != d._month
|| _day != d._day;
}
// d1 + 100
Date& Date::operator+=(int day)
{
_day += day;
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
++_month;
if (_month == 13)
{
++_year;
_month = 1;
}
}
return *this;
}
Date Date::operator+(int day)
{
Date tmp = *this;
tmp += day;
return tmp;
}
// d1 - 100
Date Date::operator-(int day)
{
Date tmp = *this;
tmp -= day;
return tmp;
}
Date& Date::operator-=(int day)
{
_day -= day;
while (_day <= 0)
{
--_month;
if (_month == 0)
{
_day = 31 + _day;
}
else
{
_day = GetMonthDay(_year, _month) + _day;
}
if (_month == 0)
{
--_year;
_month = 12;
}
}
return *this;
}
// ++d1
Date& Date::operator++()
{
*this += 1;
return *this;
}
// 特殊处理:解决语法逻辑不自洽,自相矛盾的问题
// d1++
// 为了跟前置++区分,强行增加一个int形参,够成重载区分
Date Date::operator++(int)
{
Date tmp = *this;
*this += 1;
return tmp;
}
//Date Date::operator--(int)
//{
//
//}
//
//Date& Date::operator--()
//{
//
//}
// d1 - d2
int Date::operator-(const Date& d)
{
Date max, min;
max = *this;
min = d;
int n = 0;
if (max < min)
{
max = d;
min = *this;
}
while (min != max)
{
min++;
n++;
}
return n;
}