C++(四)类和对象-默认的成员函数

隐含的this指针

1.每个成员函数都有一个指针形参,它的名字是固定的,称为this指针,this指针是隐式的。
2.编译器会对成员函数进行处理,在对象调用成员函数的时候,对象地址作为实参传递给成员函数的第一个形参this指针。
3.this指针是成员函数隐含指针形参,是编译器自己处理的,我们不能在成员函数的形参中添加this的参数定义,也不能在调用时,显示传递对象的地址给this指针。

类的默认成员函数
这里写图片描述

我们定义一个日期类作为例子

class Date
{
public:
    void Display()
    {
        cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
    }
    private:
        int _year;
        int _month;
        int _day;
};

日期的成员变量是私有的,我们怎么初始化这些私有的成员变量?

1.构造函数

成员变量为私有的,要对他们进行初始化,必须用一个共有函数来进行,同时这个函数应该有且仅在定义对象时自动执行一次,这时调用的函数称为构造函数。

构造函数是特殊的成员函数,它的特征:
1.函数名与类名相同。
2.无返回值。
3.对象构造时系统自动调用对应的构造函数。
4.构造函数可以重载。
5.构造函数可以在类中定义,也可以在类外定义。
6.如果类定义中没有给出析构函数,则C++编译器自动产生一个缺省的构造函数,但只要我们定义了一个构造函数,系统就不会自动生成缺省的构造函数。
7.无参的构造函数和全缺省的构造函数,都认为是缺省构造函数,并且缺省构造函数只能有一个

无参构造函数&带参构造函数
class Date
{
public:
    //1.无参构造函数
    Date()
    {}

    //2.带参构造函数
    Date(int year,int month,int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    private:
        int _year;
        int _month;
        int _day;
};
void TestDate1()
{
    Date d1;
    Date d2(2015,1,1);
}

带缺省参数的构造函数

Date(int year = 2000,int month = 1;int day = 1)
{
    -year = year;
    _month = month;
    _day = day;
}

拷贝构造函数

创建对象时使用同类对象来进行初始化,这时所用的构造函数称为拷贝构造函数,拷贝构造函数是特殊的构造函数。

特征:
1.拷贝构造函数其实是构造函数的重载。
2.拷贝构造函数的形参必须使用引用传参,使用传值方式会引起无限递归调用。
3.若未显示定义,系统会默认缺省的拷贝构造函数。缺省的拷贝构造函数会依次拷贝类成员进行初始化、

class Date
{
public:
    Date()
    {}
    //拷贝构造函数
    Date(const Date& d)
    {
        _year = d._year;
        _month = d._month;
        _day = d._day;
    }//在这里我们对象可以直接访问私有的成员变量
    //1.在类的成员函数中可以直接访问同类对象的私有/保护成员
    //2.C++的访问限定符是以类为单位的,也就是说在这个单位内的成员可以互相访问。
private:
    int _year;
    int _month;
    int _day;
};
void TestDate1()
{
    Date d1;
    //下面两种用法都是调用拷贝构造函数,是等价的。
    Date d2(d1);
    Date d3 = d1;
}

析构函数

当一个对象的生命周期结束时,C++编译系统会自动调用一个成员函数,这个特殊的成员函数就是析构函数。
析构函数是特殊的成员函数特征如下:
1.析构函数在类名上加字符~。
2.析构函数无参数返回值。
3.一个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省的析构函数。
4.对象生命周期结束时,C++编译系统自动调用析构函数。
5.注意析构函数体内并不是删除对象,而是做了一些清理工作。

赋值运算符重载

拷贝构造函数是创建的对象,使用一个已有对象来初始化这个准备创建的对象。
赋值运算符的重载是对一个已经存在的对象进行拷贝赋值

class Date
{
public:
    Date()
    {}
    //拷贝构造函数
    Date(const Date& d)
        :_year(d._year)
        ,_month(d._month)
        ,_day(d._day)
    {}

    //赋值操作符的重载
    Date& operator=(const Date& d)
    {
        if(this != &d)//判断是不是本身
        {
            this->_year = d._year;
            this->_month = d._month;
            this->_day = d._day;
        }
        return *this;
        //我们的this 被赋值了,而且出了函数还存在,那么就要拿Date类型来接收参数
    }
private:
    int _year;
    int _month;
    int _day;
};
void Test()
{
    Date d1;
    Date d2 = d1;//调用拷贝函数
    Date d3;
    d3 = d1;//调用赋值运算符的重载
}

深入探索构造函数

类的成员变量有两种初始化方式:
1.初始化列表。
2.构造函数体内进行复制。

初始化列表以一个冒号开始,接着一个都要分隔数据列表,每个数据成员都放在一个括号中进行初始化。尽量使用初始化列表进行初始化,因为它更高效。

哪些成员变量必须放在初始化列表里面?
1.常量成员变量。
2.引用类型成员变量。
3.没有缺省构造函数的类成员变量。

成员变量按声明顺序依次初始化,而费初始化列表出现的顺序

©️2020 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值