C++学习-类和对象(二)

this指针

先来看下面代码

#include<iostream>
using namespace std;
class Person
{
    public:
        void Display()
        {
            cout<<_name<<"-"<<_age<<"-"<<_id<<endl;
        }
    public:
        char* _name;
        int   _age;
        int   _id;
};
int   main()
{
    Person p;
    p._name="jack";
    p._age=20;
    p._id=123456;
    p.Display();

    Person *point=&p;

    point->_name="Rose";
    point->_age=21;
    point->_id=654321;
    point->Display();
    return 0;

}

运行结果

[zyc@localhost lession_class]$ ./a.out 
jack-20-123456
Rose-21-654321

为什么调用同样的函数,但是结果却不一样呢?

原因就在于this指针。

下面来看什么是this指针。

1.概念

this指针是一个隐含的指针,它是指向对象本身,代表了对象的地址。

正如你家有个人名叫“狗蛋”的,你隔壁家也有个人叫“狗蛋”。this就表示你自家的人,说明白一点就是你家的那个“狗蛋”。

隐含的指针的说法,可以形象化成这样:

当你进入一个房子后,你可以看见桌子、椅子、地板等,但是房子你是看不到全貌了。
对于一个类的实例来说,你可以看到它的成员函数、成员变量,但是看不到实例本身。

this是一个指针,它时时刻刻指向你这个实例本身。

即使调用相同的构造函数,但是由于调用时传给this指针的实例对象不同,所以打印的对象也就不同,

开始 时this是实例p的地址。随后this是实例point的地址。

这里写图片描述

2.this特性特性

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

4.this指针是实参,调用函数时产生,所以this指针 存放在栈上

5.不可以显示传递this,不识别,可以在函数里面显示写this
6.有些平台为提高效率 将this指针存放在寄存器ecx中,下次要用直接在寄存器中取。比如windows.


类的6个默认成员函数

这里写图片描述

1.构造函数

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

下面来看代码

1)默认构造函数(编译自动生成)

#include<iostream>
using namespace std;
class Data
{
    public:
        //无参的构造函数

        void Display()
        {
            cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
        }


    private:
        int _year;
        int _month;
        int _day;

};
int main()
{
    Data d1;
    Data d2;


    d1.Display();
    d2.Display();
    return 0;

}

运行结果:

[zyc@localhost lession_class]$ ./a.out 
1376536704-32767-0
0-0-4196208
结果分析:

默认构造函数,生成随机值。一旦用户自己定义构造函数,即使时无参的构造函数,系统也不会自动生成构造函数。

2)自定义构造函数

1.无参构造函数
2.带参的构造函数(全缺省参数,半缺省参数)

#include<iostream>
using namespace std;
class Data
{
    public:
        //无参的构造函数
        Data()
        {
            _year=1900;
            _month=1;
            _day=1;
        }
        //带参的构造函数
        Data(int year,int month,int day)
        {
            _year=year;
            _month=month;
            _day=day;

        }
        void Display()
        {
            cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
        }


    private:
        int _year;
        int _month;
        int _day;

};
int main()
{
    Data d1;
    Data d2;
    //Data d2();无参时,后面不要加括号(直接使用无参的构造函数
    //会报错,会被 编译器忽略
    Data d3(2018,1,1);


    d1.Display();
    d2.Display();
    d3.Display();
    return 0;

}
#include<iostream>
using namespace std;
class Data

{
    public:
        //Data();不能与下面构造函数共存,否则会报错:调用重载的“Data()”是不明确的


        //带参的缺省的构造函数,推荐使用
        //传参个数随意
        Data(int year=1900,int month=1,int day=1)
        {
            _year=year;
            _month=month;
            _day=day;

        }
        void Display()
        {
            cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
        }
        ~Data()//析构函数
        {

        }


    private:
        int _year;
        int _month;
        int _day;

};
int main()
{

    Data d1;//调用无参的构造函数


    Data d2(2018,1,1);//调用带参的构造函数


    Data(2018,7,10).Display();//匿名对象

    d1.Display();
    d2.Display();
    return 0;

}
[zyc@localhost lession_class]$ ./a.out 
2018-7-10   //匿名对象
1900-1-1    //d1
2018-1-1    //d2

总结构造函数:

构造函数是特殊的成员函数,其特征如下:

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

析构函数

当一个对象的生命周期结束时,C++编译系统会自动调用一个成员函数,这个特殊的成员函数即析构函数(destructor)
构造函数是特殊的成员函数,其特征如下:
1. 析构函数在类名加上字符~。
2. 析构函数无参数无返回值。
3. 一个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省的析构函数。构造函数可以有多个。
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
5. 注意析构函数体内并不是删除对象,而是做一些清理工作。所谓清理通常指释放一些malloc申请的空间,并将其置为空。防止内存泄露
6. 析构函数不可重载,重载没有实际意义。

#include<iostream>
#include <stdlib.h>
using namespace std;
class Array
{
    public:
        //构造函数
        Array(int size)
        {
            _ptr=(int *)malloc(size*sizeof(int));

        }

        //这里的析构函数需要完成清理工作(释放空间)

        ~Array()
        {
            if(_ptr)
            {
                free(_ptr);
                _ptr=NULL;
            }
        }


    private:
        int *ptr;

};

析构函数总结:

析构函数有自动生成和自定义两种类型。一般有malloc等函数申请空间时最好使用自定义析构函数。

析构函数和构造函数比较

功能 函数名 产生方式 是否可以重载 个数限制
构造函数 初始化变量 自动生成/自定义 可重载 一个类可以有多个构造函数
析构函数 清理工作 自动生成/自定义 不可重载 一个类只有一个析构函数

猜你喜欢

转载自blog.csdn.net/zgege/article/details/80990940
今日推荐