C++基础----类和对象(二)

C++基础----类和对象(二)

类的6个默认成员函数

在这里插入图片描述

构造函数

构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,

以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次

特性

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

析构函数

析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由

编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作

特性

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

class Stack
{
public:
    //构造函数
    Stack(size_t capacity = 3)
 {
 	_array = (DataType*)malloc(sizeof(DataType) * capacity);
 	if (NULL == _array)
 	{
 		perror("malloc申请空间失败!!!");
 		return;
 	}
 		_capacity = capacity;
		_size = 0;
 }
    //析构函数
    //由于栈开辟的空间是在堆上,需要手动释放,故需要自己定义析构函数
    ~Stack()
 {
 	if (_array)
 	{
 		free(_array);
 		_array = NULL;
		_capacity = 0;
		_size = 0;
 	}
 }
class Time
{
public:
 	~Time()
 {
 	cout << "~Time()" << endl;
 }
private:
 	int _hour;
 	int _minute;
 	int _second;
};
class Date
{
	private:
 	// 基本类型(内置类型)
 	int _year = 1970;
 	int _month = 1;
 	int _day = 1;
 	// 自定义类型
 	Time _t;
};
int main()
{
 	Date d;
 	return 0;
}
// 程序运行结束后输出:~Time()
// 内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可;而_t是Time类对象,
// 所以在 d销毁时,要将其内部包含的Time类的_t对象销毁,所以要调用Time类的析构函数。
// 但是main函数中不能直接调用Time类的析构函数,实际要释放的是Date类对象,所以编译器会调用Date类的析构函数
// 而Date没有显式提供,则编译器会给Date类生成一个默认的析构函数,目的是在其内部调用Time类的析构函数
// 即当Date对象销毁时,要保证其内部每个自定义对象都可以正确销毁

拷贝构造函数

拷贝构造函数:只有单个形参该形参是对本类类型对象的引用(一般常用const修饰)

在用已存在的类类型对象创建新对象时由编译器自动调用。

特征

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

赋值运算符重载

运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数

也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

在这里插入图片描述
在这里插入图片描述

日期类的运算符重载

class Date
{
public:
	//任何一个类,只需要写一个> == 或者< ==重载
	//剩下的比较运算符重载复用即可
	//==运算符重载
	bool operator==(const Date& d2)
	{
		return _year == d2._year
			&& _month == d2._month
			&& _day == d2._day;
	}
	// >运算符重载
	bool operator>(const Date& d)
	{
		if (_year > d._year
			|| (_year == d._year && _month > d._month)
			|| (_year == d._year && _month == d._month && _day > d._day)
			)
			return true;
		else
			return false;
	}
	// >=运算符重载
	bool operator >= (const Date& d)
	{
		return (*this>d)||(*this==d);
	}
	// <运算符重载
	bool operator < (const Date& d)
	{
		return !(*this >= d);
	}
	// <=运算符重载
	bool operator <= (const Date& d)
	{
		return !(*this > d);
	}
	// !=运算符重载
	bool operator != (const Date& d)
	{
		return !(*this == d);
	}
	static int getm(int year, int month)
	{
		int arrm[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;
		}
		else
		{
			return arrm[month];
		}
	}
	//date+100 运算符重载
	Date operator+(int d)
	{
		Date ret(*this);
		ret._day+=d;
		while (ret._day > getm(ret._year,ret._month))
		{
			ret._day-=getm(ret._year, ret._month);
			ret._month+=1;
			if (ret._month = 13)
			{
				ret._month = 1;
				ret._year+=1;
			}
		}
		return ret;
	}
	//date+=100 运算符重载
	//方法一:
	Date operator+=(int d)
	{
		_day += d;
		while (_day > getm(_year, _month))
		{
			_day -= getm(_year, _month);
			_month += 1;
			if (_month > 12)
			{
				_year += 1;
			}
		}
		return *this;
	}
	//方法二:
	//效率差,调用了两次拷贝构造函数
	Date operator+=(int d)
	{
		*this = *this + d;
		return *this;
	}
	//d1-d2
	//运算符重载  日期减少日期 结果是天数
	int operator-(Date d)
	{
        
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;   //年
	int _month;  //月
	int _day;    //日
};
int main()
{
	Date d1;
	Date d2;	
	//d1.operator++(&d1)
	++d1;
	//d1.operator++(&d2,0)
	//后面只要传的是整数就行,是由编译器决定的
	d2++;
	return 0;
}


前置++和后置++重载

	//++d1
	//d1++
	//直接按特性重载,无法区分
	//特殊处理,使用重载区分,
	//后置++重载增加一个int参数跟前置构成函数重载进行区分
	Date& operator++()//前置
	{
		*this += 1;
		return *this;
	}
	Date operator++(int)//后置
	{
		Date tmp(*this);
		*this += 1;
		return tmp;
	}

赋值运算符重载格式

参数类型:const T&,传递引用可以提高传参效率

返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值

检测是否自己给自己赋值

返回this :要复合连续赋值的含义

//赋值运算符重载
	//*this出了这个函数的作用域还在,故用传引用返回,提高效率
	Date& operator=(const Date& d)
	{
		//if是为了防止 出现d1=d1的情况,提高效率
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
        //应对连续赋值的情况
		return *this;
	}

在这里插入图片描述

取地址及const取地址操作符重载

const成员

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,

实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改

在这里插入图片描述
在这里插入图片描述

取地址操作符重载

class Date
{ 
//两个函数构成重载
//他们是默认成员函数,我们不写编译器会自动生成
//默认生成的就够用了,一般不需要我们自己写
public :
 Date* operator&()
 {
 	return this;
 }
 const Date* operator&()const
 {
 	return this;
 }
//特殊情况:当不想让别人取到这个类型对象的地址时,需要自己写
 Date* operator&()
 {
 	return nullptr;
 }
 const Date* operator&()const
 {
 	return nullptr;
 }
private :
 int _year ; // 年
 int _month ; // 月
 int _day ; // 日
};

总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值