对6个默认成员函数的总结

前言:本篇文章是对六大默认成员函数的自我总结,不适合刚入门的新人学习。适合想进一步深入了解六大默认成员函数的人学习。

1.构造函数:给对象初始化的函数,相当于之前写的Init函数。

构造函数的特性:

对内置类型不做处理(也可处理,取决于编译器),对自定义类型:去调用它的默认构造函数(下面会提到默认构造函数包括哪几类)。

不写返回值

函数的名字就是类名

可以函数重载(不同的初始化方式)

对对象初始化

string Date
{
public:
    Date(int year=1;int month=1;int day=1)
    {
        int _year=year;
        int _month=month;
        int _day=day;
    }
private:
    int _year;
    int _month;
    int _day;
}

这一段代码写了构造函数:没有返回值,函数名就是Date,全缺省,赋初值。


string Date
{
public:
    Date(int year=2024;int month=4;int day=26)
    {
        int _year=year;
        int _month=month;
        int _day=day;
    }
private:
    int _year=1;
    int _month=1;
    int _day=1;
}

这一段代码,多了一个缺省值,注意,int _year=1;int _month=1;int _day=1这里是声明,不是定义。

这一段代码,会先走int _year=1;int _month=1;int _day=1这一段,然后再进入构造函数体内部。

整体的进行过程,先把年月日用缺省值的1,然后进入函数体内部,在对年月日赋初值。

(注意:如果有初始化列表,就不会走缺省值)

//构造函数
Date(int year = 1, int month = 1,int day=1)
	:_year(year)
	,_month(month)
	,_day(day)
{}

有初始化列表,就不会走缺省值那一条路。


默认构造函数:

1.无参的

2.全缺省的

3.编译器自动生成的

(为什么要有默认构造函数这个概念?-->对于自定义类型,会去调用它的默认构造函数)


注意点:

没有写构造函数,写了拷贝构造-->编译器就不会自动生成构造函数(对内置类型:不做处理。对自定义类型:调用对应的构造函数)

写了构造,没写拷贝构造-->编译器会自动生成拷贝构造(对内置类型:浅拷贝,值拷贝。对自定义类型:调用类对象的拷贝构造)


2.析构函数:

特点:

     1.函数名前面加~

     2.函数名就是类名

     3.不需要传参

     4.一个类里面只能写一个析构函数

     5.析构函数是资源的清理,而不是销毁数据


3.拷贝构造:

特点:

1.需要传引用传参(否则会发生无穷递归:传自定义类型需要调用对应的拷贝构造)

2.没有返回值

3.拷贝的对象和被拷贝的对象的类型一致

4.对于内置类型:浅拷贝

5.对于自定义类型:调用类的拷贝构造(所以如果不是传引用传参,会发生无穷递归)

6.拷贝构造也可以写初始化列表,也会去走缺省值的地方 

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

拷贝构造的使用:

Date d1(2024,4,26);

Date d2(d1);//拷贝构造

Date d2=d1;//拷贝构造(注意注意,这里是拷贝构造)


区分:

拷贝构造和赋值重载

Date d1=d2;//拷贝构造

d1=d2;//赋值重载

拷贝构造是一个特殊的构造函数,构造-->初始化对象,拿d2的值去初始化d1

赋值重载,是两个已经存在的对象,拿d2的值去赋给d1。把d1原来的值覆盖掉。


运算符重载:

1.这一类的函数的返回值和参数是和运算符的类型有关的。

1.    bool operator<(const Date& d1,const Date& d2);

2.    Date operator+=(int day);                  //里面可以是内置类型

3.    int operator--(const Date& d1,const Date& d2); 

2.运算符重载中必须要有一个自定义类型。

 3.如果写成成员函数,参数要少一个。

4.下面5中运算符不能重载    .*(点星)    ::(域限定符)    sizeof    ?:(三目运算符)    .(对象点)

5.如果成员函数和全局的同时存在,会先去调用成员函数的。那时候全局的就没有意义了。

如果类里面没有,就会去全局中找。找不到就报错。

6.前置++    Date& operator++()

  后置++     Date& operator++(int)       规定后置++多一个int参数,这个参数只是为了识别前置后置

                              (不能double,char,只是为了让编译器区分) 

//前置++
Date& operator++()
{
	*this += 1;
	return *this;
}

//后置++
Date operator++(int)
{
	Date tmp(*this);
	*this += 1;
	return tmp;
}

对于自定义类型,后置++的消耗更大,拷贝构造tmp变量 ,然后又传值返回


 4.赋值重载:

把=这个运算符进行重载,让它可以运用在自定义对象里面。 

赋值重载的函数的返回值可以是void,但是我们通常这样子写。

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

1.代码的意思?

            把d1的值赋给this指针指向的变量,然后再返回*this,让*this作为下一个赋值的右操作数。

        就形成了练习赋值。

2.为什么要写成Date&

             因为要支持连续赋值。

3.为啥要传引用返回?

            不用创建临时变量(临时变量需要调用拷贝构造),传引用返回-->别名

       临时变量具有常性。

4.注意点:规定赋值重载不能写成全局的。其他重载可以。


拷贝构造和赋值重载:

对于内置类型:按字节拷贝(赋值)

对自定义类型:会去调用它的拷贝构造(赋值重载)


5.取地址重载:

对取地址符号进行重载,让它可以对自定义类型的对象进行取地址。

默认生成就够用了,一般情况下不需要我们自己重新写。

class Date
{
public:
     Date* operator&()   //就只有一个参数this
     {
        return this;
     }
private:
    int _year;
    int _month;
    int _day;
}

Date d1;

cout<<&d1;


6.const取地址重载:

   对于const修饰的自定义类型,也重载了并且编译器自动生成。

 返回类型要加const,对this也加const

class Date
{
public:
     const Date* operator&() const  //就只有一个参数this
     {
        return this;     //返回的this是不可以修改的,所以返回类型加了const
     }
private:
    int _year;
    int _month;
    int _day;
}

 const Date d1;

cout<<&d1;


对于取地址重载和const修饰的取地址重载,平时我们不需要管它,只需要我们可以用来对自定义类型的对象进行取它的地址就可以了。 我们不需要显示的写。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值