C++初阶(长期更新)第5讲:类和对象(中)

C++初阶(长期更新)第5讲:

类和对象(中)

++跟着潼心走,轻松拿捏C++,困惑通通走,一去不回头~欢迎开始今天的学++ ++习内容,你的支持就是博主最大的动力++ 。博主主页:潼心1412o-CSDN博客


前言

今天继续学习上节课没有学习完的运算符重载的内容,gogogo,出发喽~

5.1 =赋值运算符重载

cpp 复制代码
Date& Date::operator=(const Date& d)
{
	if (this != &d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	return *this;
}

注意和拷贝构造区分开,拷贝构造是在初始化时就已经完成的

而赋值运算符重载则是已经初始化的自定义类型进行赋值

5.2 -和-=运算符重载

下面有两种方式的代码实现,都进行了代码复用

cpp 复制代码
Date& Date::operator-=(int day)
{
	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			_month = 12;
			--_year;
		}
		_day += GetMonthDays(_year, _month);
	}
	return *this;
}

Date Date::operator-(int day)
{
	Date temp(*this);
	temp -= day;
	return temp;
}
cpp 复制代码
Date Date::operator-(int day)
{
	Date temp(*this);
	temp._day -= day;
	while (temp._day <= 0)
	{
		--temp._month;
		if (temp._month == 0)
		{
			temp._month = 12;
			--temp._year;
		}
		temp._day += GetMonthDays(temp._year, temp._month);
	}
	return temp;
}

Date& Date::operator-=(int day)
{
	*this = *this - day;
	return *this;
}

同时进行计算,第一种代码进行了两次拷贝,第二次则进行了5次,所以我们优先实现-=再实现-

5.3 前后置++ --运算符重载

cpp 复制代码
Date& Date::operator++()
{
	*this += 1;
	return *this;
}
Date Date::operator++(int)
{
	Date temp(*this);
	*this += 1;
	return temp;
}
Date Date::operator--()
{
	*this -= 1;
	return *this;
}
Date Date::operator--(int)
{
	Date temp(*this);
	*this -= 1;
	return temp;
}

前置后置的区分方式是 后置加一个int类型的参数

在使用时就这样调用,注意显式调用时一定要传一个int类型的实参

cpp 复制代码
	
d1++;
//显式调用
d1.operator++(0);

5.4 一些其他的二元运算符重载

cpp 复制代码
bool  Date::operator==(const Date d)
{
	return _year == d._year
		&& _month == d._month
		&& _day == d._day;
}

bool  Date::operator!=(const Date d)
{
	return !(*this == d);
}

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);
}

5.5 \[\]运算符重载

cpp 复制代码
class SeqList
{
public:
	int& operator[](size_t x)
	{
		return _a[x];
	}
private:
	int _a[10];
	int _size;
};

void Test01()
{
	SeqList s;
	for (size_t i = 0; i < 10; i++)
	{
		s[i] = i;
		cout << s[i];
	}
	cout << endl;
}

5.6 d1-d2

cpp 复制代码
int Date::operator-(const Date& d)
{
	Date max = *this;
	Date min = d;
	int flag = 1;
	int count = 0;
	if (max < min)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	while(max!=min)
	{
		--max;
		++count;
	}
	return count * flag;
}

5.7 cout cin流插入流提取

以前面的经验,很自然地我们写出如下代码

cpp 复制代码
ostream& Date::operator<<(ostream& out)
{
	out << _year << "/" << _month << "/" << _day;
	return out;
}

istream& Date::operator>>(istream& in)
{
	in >> _year >> _month >> _day;
	return in;
}

但是在调用时我们发现由于前面要求运算符重载如果是二元的话两个操作数必须按顺序传入函数但是这里this占据了默认的第一个位置,而我们一般cout是在左边的操作数,非要用只能这么写

cpp 复制代码
Date d2;
d2 >> cin;
d2 << cout;

在调用时就非常不符合我们的使用习惯,降低了代码的可读性,所以我们不用一直放在类里面而是可以通过友元的方式使用全局函数进行流插入流提取的运算符重载

cpp 复制代码
//Date类内...
friend ostream& operator<<(ostream& out, const Date& d);
friend istream& operator>>(istream& in, Date& d);

//检查日期类是否合法
bool Date::CheckDate()
{
	if (_month < 0 || _month>12 || _day <= 0 || _day > GetMonthDays(_year, _month))
	{
		return false;
	}
	return true;
}

//全局函数
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "/" << d._month << "/" << d._day;
	return out;
}

istream& operator>>(istream& in, Date& d)
{
	while (1)
	{
		in >> d._year >> d._month >> d._day;
		if (d.CheckDate())
		{
			break;
		}
		else
			cout << "非法输入,请重新输入->" << endl;
		}
return in;
}

5.8 取地址运算符重载

5.8.1 const成员函数

将const修饰的成员函数称之为const成员函数,const修饰成员函数放到成员函数参数列表的后
⾯。const实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改
隐含的this指针由 Date* const this 变为 const Date* const this

5.8.2 取地址运算符重载

cpp 复制代码
Date* Date::operator&()
{
	return this;
	//return nullptr;
}

const Date* Date::operator&() const
{
	return this;
	//return nullptr;
}

一般不用,除了不想让这个地址被拿到起一个保护作用


++好了今天的学习内容就到这里啦,谢谢你的陪伴,我是潼心,下次再见~如果这篇文章对你有帮助的话。请务必给主播一个一键三连,球球了,这对主播很重要~++

博主主页:潼心1412o-CSDN博客

相关推荐
weixin_307779131 小时前
C++代码实现MATLAB中的normalize函数功能
开发语言·c++·算法·matlab
谢亮_vipxieliang1 小时前
Go WaitGroup与Once——并发同步的基石
开发语言·后端·golang
(Charon)1 小时前
【C++面试】手写String类:同时实现拷贝构造与移动构造
c++·算法
程序员老陆1 小时前
通过std::unique_ptr初始化std::shared_ptr
开发语言·c++
liangshanbo12152 小时前
前端面试题:AI 对话中超长消息导致内存溢出,怎么解决?
java·开发语言·前端
北冥you鱼2 小时前
Go 语言 Channel 机制详解:从原理到实战
开发语言·后端·golang
谢亮_vipxieliang2 小时前
Go 并发控制进阶:sync 包高级原语与 Context 生命周期管理
开发语言·后端·golang
xuxigifxfh2 小时前
HJ5 进制转换
java·开发语言·华为机考
denlaku2 小时前
JDK 12 新特性详解
java·开发语言