📪1.const成员
📪将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改
ostream& operator<<(ostream& out, const Date& d)
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return out;
}
📟输入的语法规则则为
istream& operator>>(istream& in, Date& d)
{
in >> d._year >> d._month >> d._day;
return in;
}
📮见下图能否帮助你理解一下
🔫2.取地址及const取地址操作运算符重载
🎾下面我们正式进入今天的主题
来看下面两段代码
#include "Date.h"
Date::Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
if (_year < 1 ||
_month < 1 || _month > 12 ||
_day < 1 || _day > GetMonthDay(_year, _month))
{
Print();
cout << "日期非法" << endl;
}
}
void Date::Print() const
{
cout << _year << "/" << _month << "/" << _day << endl;
}
bool Date::operator==(const Date& y) const
{
return _year == y._year
&& _month == y._month
&& _day == y._day;
}
bool Date::operator!=(const Date& y) const
{
return !(*this == y);
}
bool Date::operator>(const Date& y) const
{
if (_year > y._year)
{
return true;
}
else if (_year == y._year && _month > y._month)
{
return true;
}
else if (_year == y._year && _month == y._month && _day > y._day)
{
return true;
}
return false;
}
bool Date::operator>=(const Date& y) const
{
return *this > y || *this == y;
}
bool Date::operator<(const Date& y) const
{
return !(*this >= y);
}
bool Date::operator<=(const Date& y) const
{
return !(*this > y);
}
int Date::GetMonthDay(int year, int month)
{
assert(year >= 1 && month >= 1 && month <= 12);
int monthArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,31 };
if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
return 29;
return monthArray[month];
}
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 Date::operator+(int day) const
{
Date tmp(*this);
tmp += day;
return tmp;
}
Date& 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;
}
Date Date::operator-(int day) const
{
Date tmp(*this);
tmp -= day;
return tmp;
}
Date& Date::operator++()
{
*this += 1;
return *this;
}
Date Date::operator++(int)
{
Date tmp(*this);
*this += 1;
return tmp;
}
Date& Date::operator--()
{
*this -= 1;
return *this;
}
Date Date::operator--(int)
{
Date tmp(*this);
*this -= 1;
return tmp;
}
int Date::operator-(const Date& d) const
{
int flag = 1;
Date max = *this;
Date min = d;
if (*this < d)
{
max = d;
min = *this;
flag = -1;
}
int n = 0;
while (min != max)
{
++min;
++n;
}
return n * flag;
}
ostream& operator<<(ostream& out, const Date& d)
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return out;
}
istream& operator>>(istream& in, Date& d)
{
in >> d._year >> d._month >> d._day;
return in;
}
🚿思考下面问题
📲1. const对象可以调用非const成员函数吗?
📲2. 非const对象可以调用const成员函数吗?
📲解析:能定义成const的成员函数都应该定义成为const 这样对const对象和非const成员来说都可以调用 要修改成员变量的成员函数不能定义成const
📲上述问题归根结底还是我们的权限的放大缩小和平移的问题
class Stack
{
public:
Stack(int n = 2)
:_a((int*)malloc(sizeof(int)*n))
,_top(0)
,_capacity(n)
{
if (_a == nullptr)
{
perror("malloc fail");
exit(-1);
}
memset(_a, 0, sizeof(int) * n);
}
int* _a;
int _top;
int _capacity;
};
📲上述代码给大家写了一下初始化列表和函数体的运用规则 对于const成员和引用成员必须在初始化列表初始化 不能再函数体内部初始化 初始化列表也可以运用函数 比如malloc 然后在函数体内判断是否为NULL 在进行memset操作
📲来看下面的一道面试题
class A
{
public:
A(int a)
:_a1(a)
, _a2(_a1)
{}
void Print() {
cout << _a1 << " " << _a2 << endl;
}
private:
int _a2;
int _a1;
};
int main()
{
A aa(1);
aa.Print();
}