C++类和对象、四个默认成员函数、运算符重载

C++类和对象、四个默认成员函数、运算符重载

一.C++类的理解:

1.类:类是面向对象的一个概念,类其实可以说是一种用户自定义的数据类型,而比基本的数据类型,比如:int、long、double等等,只不过基本数据类型已经定义好了,可以直接拿来用,而类需要用户根据需要编写出来才行。

2.类的特点:C++类可以分为两类:①entity类(实体类),②function(功能类)对于构造entity的类,包括这种entity的属性已经在它本身就具备的工能,而function的类,就是包括entity的功能以及一些参数,但是这些功能不是entity本身具备的。这种类构造函数通常用于传入参数,i、e实体。如果实体的数据量比较大,通常这个参数采用指针,所以可以节省内存通过一个地址获取数据。

3.对于声明类的时候要不要用指针的一方法就是如果是实体类,一般不需要,而如果是功能类,因为处理实体,而实体的数据量比较大,也可以不使用指针,而是在构造函数传入参数的地方使用用指针。
A.类的三大特性:
①封装②继承③多态
B.类的三种访问限定符:
①public(公有)②protected(保护)③private(私有)。public:public成员可以从类外部直接访问,private/protected成员不能从外部直接访问;每个限定符在类体内可以使用多次,它的作用域是从该限定符出现开始到下一个限定符之前或类体结束前;类体中如果没有限定符,则默认为私有;类的访问限定符体现了面向对象的封装性。
C.作用域:①局部域②全局域③类域④名字空间域。
类的作用域:
1.每个类都定义了自己的作用域,类的成员(成员函数/成员变量)都在类这个作用域内,成员函数内可任意访问它的成员变量和其他成员函数。
2.对象可以通过 .直接访问公有成员,指向对象的指针通过->也可以直接访问对象的公有成员。
3.在类体外定义成员,需要使用::作用域解析符指明成员属于哪个类域。
定义简单的类:这里写图片描述
对象:
1.类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来储存它。
2.一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间储存类成员。
3.类实例化出的对象就像现实中使用建筑设计图建造房子,类就像设计图,只设计出需要的东西,并没有实体的建筑存在,同样的类也只是一个设计,实际化出的对象才能实际储存数据,占用物理空间。

Alt text
Alt text

下面是测试空类和类对齐后的占内存大小:这里写图片描述这里写图片描述

这里写图片描述

二.四个成员函数:①构造函数②拷贝函数③析构函数④赋值操作重载符

1.构造函数:成员变量是私有的,要对它们进行初始化,必须用一个公有成员函数来进行。同时这个函数应该有且仅在定义对象时自动执行一次,这时调用的函数为构造函数(construct)。
class date
{
public:
    date()//无参构造函数
    {}
    date(int year,int month,int day)//带参构造函数
    {
        _year=year;
        _month=month;
        _day=day;
    }
    void display()
    {
        cout<<"year:"<<_year<<"_month:"<<_month<<"_day:"<<_day<<endl;
    }
private:
    int _year;
    int _month;
    int _day;
};
void test()
{
    date d1;
    date d2(2017,6,26);
    date d3();// 注意这里没有调用d3的构造函数定义出 d3
    d1.display();//因为没有赋值所以为随机值
    d2.display();
}
int main()
{
    test();
    return 0;
}
缺省参数的构造函数:
class Date
{
public:
    Date(int year=2017,int month=1,int day=1)//全缺省的构造方法
    {
        _year=year;
        _month=month;
        _day=day;
    }
    Date(int year,int month=1)//半缺省的构造方法
    {
        _year=year;
        _month=month;
        _day=1;
    }
    void display()
    {
        cout<<"year:"<<_year<<"_month:"<<_month<<"_day:"<<_day<<endl;
    }
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    Date d1(2017,6,25);
    Date d2();
    d1.display();
    d2.display();
    return 0;
}
特点:
  1. 函数名与类名相同。
  2. 无返回值。
  3. 对象构造(对象实例化)时系统自动调用对应的构造函数。
  4. 构造函数可以重载。
  5. 构造函数可以在类中定义,也可以在类外定义。
  6. 如果类定义中没有给出构造函数,则C++编译器自动产生一个缺省的构造函数,但只要我们定义了一个构造函数,系统就不会自动
    生成缺省的构造函数。
  7. 无参的构造函数和全缺省值的构造函数都认为是缺省构造函数,并且缺省的构造函数只能有一个。

三.拷贝构造函数:

理解:创建对象时使用同类对象来进行初始化,这时所用的构造函数称为拷贝构造函数(Copy Constructor),拷贝构造函数是特殊的构造函数。
通过代码来认识一下吧:
class Date
{
public:
    Date(int year,int month,int day)//这里是一个构造函数
    {
        _year=year;
        _month=month;
        _day=day;
    }
    Date(const Date& d)//这里是一拷贝构造函数
    {
        _year=d._year;//这里之所以能访问_year原因是存在一个默认的this指针
        _month=d._month;//即等同于this->_year、this->_month、this->_day
        _day=d._day;
    }
    void display()//这是一个成员函数
    {
        cout<<"year:"<<_year<<"_month:"<<_month<<"_day:"<<_day<<endl;//同样道理这里也有默认this指针
    }
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    Date d1(2017,3,15);
    Date d2(d1);
    d1.display();
    d2.display();
    return 0;
}
看似拷贝构造函数和构造函数一样的,实质上是有很大差别的:拷贝构造函数是通过一个存在的对象来初始化一个新创建的对象;而构造函数是在创建对象是直接进行初始化,而不是通过一个已存在的对象来完成初始化
特点:
  1. 拷贝构造函数其实是一个构造函数的重载。
  2. 拷贝构造函数的参数必须使用引用传参,使用传值方式会引发无穷递归调用。
  3. 若未显示定义,系统会默认缺省的拷贝构造函数。缺省的拷贝构造函数会,依次拷贝类成员进行初始化。

四.析构函数

:1.定义:析构函数是构造函数的互补:当对象超出作用域或动态分配的对象被删除时,将自动调用析构函数。析构函数可用于释放对象时构造在对象的生命周期中获取的资源。不管类是否定义了自己的析构函数,编译器都自动执行类中非static 数据成员的析构函数。
特点:
  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)
        {
            _year=d._year;
            _month=d._month;
            _day=d._day;
        }
        return *this;
    }
private:
    int _year;
    int _month;
    int _day;
};
void test()
{
    Date d1;
    Date d2(d1);//拷贝构造函数
    Date d3;
    d3=d1;//调用赋值运算符重载
}
int main()
{
    test();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/fangxiaxin/article/details/73821834