c++类和对象(2)

在c++的类中,就算我们什么成员函数都不写,也会有六个自动生成的默认成员函数,分别是

  • 构造函数:来完成对象的初始化
  • 析构函数:来进行清理
  • 拷贝构造:通过同类对象来初始化对象
  • 赋值重载:把一个对象赋值给另一个对象
  • 两个取地址操作符重载

构造函数

我们以简单的日期类举例,上篇文章中我们在日期类中写了一个成员函数Init来完成日期的初始化,但是如果我们每次创建完对象之后都要调用它的Init函数来初始化的话,有点太麻烦了,我们能不能像int a=1;一样在创建对象的时候就把信息填进去呢?

当然是可以的,那就是构造函数,它的名字和类名一样,没有返回值,在创建对象的时候会自动调用,下面就给一个自己写的构造函数

Date(int year = 1970, int month = 1, int day = 1)
{
	if (year > 0 && (month > 0 && month < 13) && (day > 0 && day < 32))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
		cout << "非法参数" << endl;
}

int main()
{
    Date a;
    Date b(2022,5,23);
}

无参的或是全缺省的构造函数,也包括我们不写编译器自动生成的都可以叫默认构造函数,默认构造函数只能有一个

可以看到我们创建对象a时没有给参数,他就会填入缺省参数,变成1970年1月1日,而b则是2022年5月23日

如果我们不写这个构造函数的话编译器会自动生成一个构造函数,它不会对基本数据类型进行处理,对于自定义类型会去调用它的构造函数,就是说如果我们的日期类里面还有一个成员变量class A,那么我们的默认构造函数会让年月日是随机值,并且调用class A的构造函数对A进行初始化

析构函数

析构函数要做的是去清理对象需要的资源

它的函数名就是类名加上~,就像~Date,没有参数也没有返回值,如果我们不自己写,编译器会自动生成一个,在对象的生命周期结束时,会自动调用析构函数

析构函数在日期类上并不需要,日期类里的int就像一个我们在main函数中定义的int类型一样除了main函数就销毁了,它需要做的是如果我们malloc了空间,我们要在析构函数中free这些空间,并将指针制空

如果我们没有写析构函数,那么和构造函数一样,编译器会默认生成一个,这个默认的析构函数的作用也和构造函数一样,对于基本数据类型不做处理,对于自定义类型,调用它的析构函数

拷贝构造

如果我们创建对象b时想让他和a一模一样怎么办,就需要我们的拷贝构造,拷贝构造是构造函数的重载,他的参数是对本类对象的引用,使用传值构造会出问题,因为函数传参实际上是对参数进行拷贝,而对参数拷贝就要调用拷贝构造,会一直调用拷贝构造

Date(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

至于默认生成的拷贝构造,他会进行浅拷贝,也就是值拷贝,这样的拷贝在日期类中没有问题,但是如果有一个类需要malloc一个数组,并存下它的地址p,在只拷贝的时候这个地址p会被拷贝过来,两个对象会共用同一个数组,这个时候就需要用到深拷贝,这个之后再讲

运算符重载

类对象也可以使用运算符进行加减大于小于等运算符进行运算的,只需要在类中对运算符进行重载并写好它的实现逻辑即可,他需要写成以下逻辑

返回值类型 operator(参数)
{
    实现逻辑;
}

需要注意的是.* :: sizeof ?: . 这五个运算符不能重载

就比方我们先重载一个简单的==

bool operator==(const Date& d)
{
	return ((_year == d._year) && (_month == d._month) && (_day == d._day));
}

可是==明明有两个参数,左边的对象和右边的对象,为什么我们只传了一个呢,那是因为它还有一个隐藏的参数,一个this指针,这个this指针才是函数的第一个参数,我们_year都应该看作this-> _year,我们在重载赋值运算符时返回的就是这个this指针的解引用

Date operator=(const Date& d)
{
	if (this != &d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	return *this;
}

赋值运算符的重载也是类的默认成员函数,我们如果不重载,编译器会自己生成,实现逻辑也和默认的拷贝构造一样,进行浅拷贝

取地址操作符重载

这两个默认成员函数在大部分情况下都不需要我们自己去写,如果我们自己写实现逻辑如下

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

我们可以看到第二个成员函数的后面有const,这个叫const成员函数,实际上是拿来修饰this指针的,但是this指针不能写在参数里,因此把const写在括号后面,作用是保证类的成员不被修改

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值