![在这里插入图片描述](https://img-blog.csdnimg.cn/7fd3fe98a0744bc085f0fe88dd5ca980.gif#pic_center)
📪1.const成员
📪将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改 🎈首先我们来想一想为什么在C++中我们的输出流能自动识别类型呢? 🎈这里给大家分享一个文档以及我给大家查到的知识 🎈点击查看官方C++库 🎈C++委员会已经帮我们写好的C++库 我们只需要写很短小的一截就可以自动识别类型 这是因为函数重载 类型匹配 函数名修饰规则的原因 所以我们标准的cout重载应该按照以下的语法规则书写
ostream& operator
in >> d._year >> d._month >> d._day;
return in;
}
📮见下图能否帮助你理解一下 🎓下面给大家总结一下 🎓运算符重载 C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似 函数名字为:关键字operator后面接需要重载的运算符符号 函数原型:返回值类型 operator操作符(参数列表) 🎓注意: 不能通过连接其他符号来创建新的操作符:比如operator 重载操作符必须有一个类类型参数 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不能改变其含义 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this .* :: sizeof ?: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出现 🎓*注意:.不会涉及 在后面的笔试题中可能会出现 在实际的工作中基本不会遇见
🔫2.取地址及const取地址操作运算符重载
🎾下面我们正式进入今天的主题 来看下面两段代码
// const对象和非const对象都可以调用const成员函数
// const Date d1(2023, 10, 31);
// d1.Print();
//
// Date d2(2023, 1, 1);
// d2.Print();
📢首先要记住一点的就是我们在前面已经讲过了就是权限可以平移和缩小但是不能放大 🔫d1里面传的本质是d1的地址也就是const Date* 而函数调用的参数里面却又是Date* this 所以这里是权限的放大 我们需要添加一个const 那么问题又来了 const加到哪里合适呢?看上面图片和代码 📲只要是不修改成员的日期类对象都可以加上const 这样让我们的const和非const成员都可以传过来 看下面代码
#include "Date.h"
Date::Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
if (_year
cout
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
return !(*this > y);
}
int Date::GetMonthDay(int year, int month)
{
assert(year >= 1 && month >= 1 && month
if (day
_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;
}
//
// d1 += 100
//Date& Date::operator+=(int day)
//{
// //Date d = *this + day;
// //*this = d;
//
// *this = *this + day;
// return *this;
//}
//
//Date Date::operator+(int day)
//{
// Date tmp(*this);
//
// tmp._day += day;
// while (tmp._day > GetMonthDay(tmp._year, tmp._month))
// {
// tmp._day -= GetMonthDay(tmp._year, tmp._month);
//
// ++tmp._month;
//
// if (tmp._month == 13)
// {
// tmp._year++;
// tmp._month = 1;
// }
// }
//
// return tmp;
//}
Date& Date::operator-=(int day)
{
if (day
--_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;
}
// ++d1
Date& Date::operator++()
{
*this += 1;
return *this;
}
// d1++
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;
}
// d1 - d2
int Date::operator-(const Date& d) const
{
// 假设左大右小
int flag = 1;
Date max = *this;
Date min = d;
// 假设错了,左小右大
if (*this
++min;
++n;
}
return n * flag;
}
//void Date::operator
out
//public:
// A(int a)
// :_a(a)
// {
// cout
// public:
// //Date(int year, int month, int day)
// //{
// // // 函数体内初始化
// // _year = year;
// // _month = month;
// // _day = day;
//
// // //_ref = year;
// // //_n = 1;
// //}
//
// //Date(int year, int month, int day)
// // :_year(year)
// // ,_month(month)
// // ,_day(day)
// // ,_ref(year)
// // ,_n(1)
// //{
// // // 初始化列表
// // //
// //}
//
// Date(int year, int month, int day)
// :_year(2)
// ,_ref(year)
// ,_n(1)
// ,_aa(10)
// {
// // 剩下3个成员没有在初始化列表显示写出来定义
// // 但是他也会定义,只是内置类型默认给的随机值
// // 如果是自定义类型成员会去调用它的默认构造函数
//
// // 函数体内初始化
// _year = year;
// _month = month;
// _day = day;
// }
//
// private:
// // 声明
// int _year = 1; // 缺省值
// int _month = 1;
// int _day;
//
// A _aa; // 定义类型成员(且该类没有默认构造函数时)
//
// int& _ref; // 引用 : 必须在定义的时候初始化
// const int _n; // const : 必须在定义的时候初始化
// };
//}
// 初始化列表解决的问题:
// 1、必须在定义的地方显示初始化 引用 const 没有默认构造自定义成员
// 2、有些自定义成员想要显示初始化,自己控制
// 尽量使用初始化列表初始化
// 构造函数能不能只要初始化列表,不要函数体初始化
// 不能,因为有些初始化或者检查的工作,初始化列表也不能全部搞定
// 80-100%初始化列表搞定,还有需要用函数体,他们可以混着用
class Stack
{
public:
Stack(int n = 2)
:_a((int*)malloc(sizeof(int)*n))
,_top(0)
,_capacity(n)
{
//...
//cout
public:
A(int a)
:_a1(a)
, _a2(_a1)
{}
void Print() {
cout |