🌈 个人主页:白子寰
🔥 分类专栏:C++打怪之路,python从入门到精通,数据结构,C语言,C语言题集 👈 希望得到您的订阅和支持~
💡 坚持创作博文(平均质量分82+),分享更多关于深度学习、C/C++,python领域的优质内容!(希望得到您的关注~)

目录
[this 和 *this 的区别](#this 和 *this 的区别)
[赋值运算符重载 和 拷贝构造函数 的区别](#赋值运算符重载 和 拷贝构造函数 的区别)
[传值返回 和 传引用返回 的区别](#传值返回 和 传引用返回 的区别)
[前置++ 和 后置++ 重载](#前置++ 和 后置++ 重载)
类的6个默认成员函数
1、特殊成员函数
2、不写编译器会自动生成

构造函数
概念
构造函数是初始化对象 ,不是开空间
C语言中没有初始化,会出现随机值
六个特性
函数名与类名相同
无返回值
对象实例化 自动调用 该函数
构造函数可以重载
如没有显式定义的构造函数,编译器自动生成(隐式的无参构造函数);反之,则不会自动生成
- 注:①不显式写默认构造,对于内置类型成员变量,看编译器是否处理; 对于自定义类型成员变量才会调用它的 无参构造 (不传参就可以调用的那个构造)
②默认构造函数包括:无参构造函数、全缺省构造函数、编译器默认生成的构造函数(隐式的无参构造函数)
6、内置类型成员变量 在类中声明时 可以给默认值


默认构造函数的意义
在两个栈实现一个队列,编译器给了初始化***(在某种情况下有意义)***
析构函数
概念
对象在销毁时自动调用 析构函数,完成对象中的资源清理
C语言没有写Destroy,会造成内存泄漏
四个特性
- 析构函数名在类名前加~
- 无参数无返回值
- 一个类只能析构一个函数,析构函数不能重载
- 在生命周期结束时自动调用
- 析构函数内置类型不做处理 ,自定义类型 会调用它的析构**
- 析构函数可以显式写


小结
- 有资源清理(开空间)才需要析构函数;如Stack、Queue
- 有两种场景不需要显式析构,用默认生成的就OK了
- ①没有资源清理,如Date
- ②内置类型成员没有资源需要清理,剩下的都是自定义类型成员;如MyQueue
拷贝构造函数
概念
用同类型的对象++拷贝初始化++
三个特性
- 拷贝构造函数是构造函数的一个重载形式
- 拷贝构造函数的参数只有一个且必须是类类对象的引用,使用传值方式编译器直接报错,会引发无穷递归
- 未显式定义,编译器会默认生成拷贝构造函数

总结
- 一般情况下,不需要显式写析构函数,就不用写拷贝构造函数(值拷贝)
- 如果 内部有指针 或者 一些值指向资源,需要显式写析构函数释放 ,需要写构造完成深拷贝; 如Satck、Queue、List

赋值运算符重载
运算符重载

相等操作符重载函数(比较Date中的两个对象是否相等)
在全局中
在全局中 写 operator== 函数,要屏蔽 Date类 中private,
那封装性如何保证? 用 友元 和重载成员函数解决
这里讲的是重载成员函数,把 内置类型成员 公有,这样在全局中函数就能 访问 内置类型成员
在类中
注意点
在主函数中
this 和 *this 的区别
赋值运算符重载
赋值运算符重载格式


注意点

赋值运算符重载 和 拷贝构造函数 的区别

传值返回 和 传引用返回 的区别
传值返回 会生成当前对象的一个拷贝,拷贝一个临时对象
引用返回 生成某别名,出了作用域就销毁了
总结 虽然引用返回减少了拷贝,但出了函数作用域,返回对象还在才能用引用(在静态)

前置++ 和 后置++ 重载

const成员

含义
const修饰的是*this,本质上是改变this的类型
在哪用
- 运算符重载
- 不改变自身
取地址及const取地址操作符重载
不显式实现,编译器默认生成
日期类的实现
Date.h
            
            
              cpp
              
              
            
          
          #pragma once
#include<iostream>
#include<stdlib.h>
using namespace std;
class Date
{
	// 友元函数,可以访问私有
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);
public:
	// 构造函数
	Date(int year, int month, int day);
	// 打印
	void Print();
	// 运算符重载
	// 实现</>,==就可以了,其他的复用(要建立栈帧,内联,不能声明和定义分离,在类里面定义就是内联)
	bool operator==(const Date& d) const;
	bool operator!=(const Date& d) const;
	bool operator>(const Date& d) const;
	bool operator>=(const Date& d) const;
	bool operator<(const Date& d) const;
	bool operator<=(const Date& d) const;
	static int GetMonthDay(int year, int month)
	{
		int GetMonthDayArr[] = { 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;
		}
		else return GetMonthDayArr[month];
	}
	// 检查日期是否正确
	bool checkDate()
	{
		if (_month < 1 || _month > 12 || _day <= 0 || _day > GetMonthDay(_year, _month)) return false;
		else return true;
	}
	// 日期 + 天数
	Date& operator+=(int day);
	Date operator+(int day) const;
	// 日期 - 天数
	Date& operator-=(int day);
	Date operator-(int day) const;
	// 前置++
	Date& operator++();
	// 后置++
	Date operator++(int) const;
	// 前置--
	Date& operator--();
	// 后置--
	Date operator--(int) const;
	// d1 - d2
	int operator-(const Date& d) const;
private:
	int _year;
	int _month;
	int _day;
};
// 流插入重载
ostream& operator<<(ostream& out, const Date& d);
// 流提取重载
istream& operator>>(istream& in, Date& d);Date.cpp
            
            
              cpp
              
              
            
          
          #define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"
Date::Date(int year, int month, int day)
{
	//cout << "Date(int year, int month, int day)" << endl;
	_year = year;
	_month = month;
	_day = day;
}
void Date::Print()
{
	cout << _year << "-" << _month << "-" << _day << endl;
}
bool Date::operator==(const Date& d) const
{
	return 	this->_year == d._year
		&& this->_month == d._month
		&& this->_day == d._day;
}
bool Date::operator!=(const Date& d) const
{
	return !(*this == d);
}
bool Date::operator>(const Date& d) const
{
	if (this->_year > d._year) return true;
	else if (this->_year == d._year && this->_month > d._month) return true;
	else if (this->_year == d._year && this->_month == d._month && this->_day > d._day) return true;
	return false;
}
bool Date::operator>=(const Date& d) const
{
	return *this > d || *this == d;
}
bool Date::operator<(const Date& d) const
{
	return !(*this >= d);
}
bool Date::operator<=(const Date& d) const
{
	return !(*this > d);
}
// 日期 + 天数
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)
		{
			_month = 12;
			--_year;
		}
		_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) const
{
	Date tmp = *this;
	tmp += 1;
	return tmp;
}
// 前置--
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}
// 后置--
Date Date::operator--(int) const
{
	Date tmp = *this;
	tmp -= 1;
	return tmp;
}
int Date::operator-(const Date& d) const
{
	Date max = *this;
	Date min = d;
	int n = 0, flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	while (min != max)
	{
		++min;
		++n;
	}
	return flag * n;
}
//ostream& Date::operator<<(ostream& out)
//{
//	out << _year << "-" << _month << "-" << _day << endl;
//	return out;
//}
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "-" << d._month << "-" << d._day << endl;
	return out;
}
istream& operator>>(istream& in, Date& d)
{
	cout << "请输入年、月、日:";
	in >> d._year >> d._month >> d._day;
	if (!d.checkDate()) {
		cout << "输入的日期无效,请重新输入。" << endl;
		in.clear(); // 清除错误标志
		in.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略错误输入直到下一个换行符
		return in;
	}
	return in;
}Test.cpp
            
            
              cpp
              
              
            
          
          #define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"
void test1()
{
	Date d1(2024, 9, 26);
	Date d2(2024, 9, 26);
	bool ret1 = d1 > d2;
	bool ret2 = d1 >= d2;
	bool ret3 = d1 < d2;
	bool ret4 = d1 <= d2;
	bool ret5 = d1 == d2;
	bool ret6 = d1 != d2;
	cout << ret1 << endl;
	cout << ret2 << endl;
	cout << ret3 << endl;
	cout << ret4 << endl;
	cout << ret5 << endl;
	cout << ret6 << endl;
}
void test2()
{
	Date d1(2024, 9, 26);
	Date d2(2024, 9, 26);
	// +=	// 11-15
	Date tmp = d1 -= -100;
	d1.Print();
	//tmp.Print();
	 + 
	//Date tmp2 = d2 + 50;
	//d2.Print();		// 9-26
	//tmp2.Print();	// 11-15
	//Date d3(2024, 9, 26);
	//Date d4(2024, 9, 26);
	 -=	//8-7
	//Date tmp3 = d3 -= 50;
	//d3.Print();
	//tmp3.Print();
	 - 
	//Date tmp4 = d4 - 50;
	//d4.Print();
	//tmp4.Print();
}
void test3()
{
	Date d1(2024, 9, 26);
	Date d2(2024, 9, 26);
	Date tmp = --d1;
	d1.Print();
	tmp.Print();
	Date tmp2 = d2--;
	d2.Print();
	tmp2.Print();
}
void test4()
{
	Date d1(2024, 9, 26);
	Date d2(2024, 10, 1);
	int ret = d1 - d2;
	cout << ret << endl;
}
void test5()
{
	// 流插入和流提取 / 内置类型 直接用,为什么?
	//cout << "1";
	//printf("2");
	//cout << "3";
	//printf("4");
	Date d1(2024, 9, 26);
	//d1 << cout;	// 类中
	cout << d1;		// 全局
}
void test6()
{
	Date d1(2024,9,27);
	Date d2(2024,10,1);
	cin >> d1 >> d2;
	cout << d1 << d2;
}
void test7()
{
	const Date d1(2024, 9, 27);
	Date d2(2024, 9, 27);
	bool d3 = d1 > d2;
	Date d4 = d1 - 10;
}
int main()
{
	//test1();
	//test2();
	//test3();
	//test4();
	//test5();
	//test6();
	test7();
}***********************************************************分割线*****************************************************************************
完结!!!
感谢浏览和阅读。等等等等一下,分享最近喜欢的一句话:
"我从来没有后悔对任何人好,哪怕看错人,哪怕被辜负,哪怕撞南墙,因为我对你好不代表你有多好,只是因为,我很好!"。
我是白子寰,如果你喜欢我的作品,不妨你留个点赞+关注让我知道你曾来过。
你的点赞和关注是我持续写作的动力!!!好了划走吧。



