C++【7】(this指针,对象数组和成员对象)

378 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

一、this指针

是一个隐藏在类的成员函数中的一个形参,是一个类类型的指针那个类对象调用成员函数, this 指针就指向谁。

任意一个对象在创建的时候,就会给自己几乎所有的成员函数都传递自己的地址,这个指针称之为this指针,this指针保存了当前对象的地址。

举个例子:对象p1所调用的函数,几乎所有的函数都被传递了一个p1这个对象的的指针

对于this指针的使用要求:

  • 1.不可以在初始化表中使用this指针
  • 2.在构造函数的函数体中可以用this指针
  • 3.不可以在形参列表中使用this,因为==this是C++中的一个关键字==

必须使用this指针的场景:

  • 场景一:成员变量和成员函数中的形参中的变量重名时
  • 场景二:返回自身的引用的时候(讲拷贝赋值函数时候再说)

📣注意:不是所有的成员函数都有this指针,有一些特例(static)

#include <iostream>

using namespace std;

class Person
{
public:
    Person(){}
    Person(int id, string name, int score)
    {
        printf("this = %p\n", this);
        this->id = id;
        this->name = name;
        this->score = score;
    }

    void printMsg()
    {
        cout << this->id << ", ";
        cout << this->name << ", ";
        cout << this->score << endl;
    }

private:
    int id;
    string name;
    int score;
};

int main()
{
    Person p1(1001, "zhangsan", 90);
    printf("&p1 = %p\n", &p1);
    p1.printMsg();
    return 0;
}

二、对象数组

本质是一个数组,数组的每一个元素都是对象

#include <iostream>

using namespace std;

class Person
{
public:
    Person(){cout << "无参构造函数" << endl;}
    Person(int id, string name, int score)
    {
        cout << "有参构造函数" << endl;
        this->id = id;
        this->name = name;
        this->score = score;
    }

    ~Person()
    {
        cout << "析构函数" << endl;
    }

    Person(const Person &obj)
    {
        cout << "拷贝构造函数" << endl;
        this->id = obj.id;
        this->name = obj.name;
        this->score = obj.score;
    }

    void printMsg()
    {
        cout << this->id << ", ";
        cout << this->name << ", ";
        cout << this->score << endl;
    }

private:
    int id;
    string name;
    int score;
};

void test1()
{
    //定义一个对象数组
    // 定义对象数组的时候会自动调用构造函数,空间释放会自动调用析构函数
    //Person per[6];
    
    //如果是局部初始化,初始化的位置调用有参构造,未初始化的调用无参构造
    Person p1[6] = {Person(1001, "zhangsan", 90),
                    Person(1002, "lisi", 89)};

    for(int i = 0; i < 6; i++)
    {
        p1[i].printMsg();
    }
}

int main()
{
    test1();

    return 0;
}

执行结果:没有传参的会打印出随机值

图片.png

三、成员对象

成员对象本质是一个对象,这个对象是另一个类的成员变量

private:
    int id;
    string name;
    int score;
    //成员对象,将一个类的对象作为另一个类的成员变量
    Birthday mybirth;
#include <iostream>

using namespace std;

class Birthday{
public:
    Birthday(){cout << "Birthday:无参构造函数" << endl;}
    Birthday(int year, int month, int day):
        year(year),month(month),day(day)
    {
        cout << "Birthday:有参构造函数" << endl;
    }

    ~Birthday()
    {
        cout << "Birthday:析构函数" << endl;
    }

    void setBirthdayMsg(int year, int month, int day)
    {
        this->year = year;
        this->month = month;
        this->day = day;
    }

    int getYear()
    {
        return this->year;
    }

    int getMonth()
    {
        return this->month;
    }

    int getDay()
    {
        return this->day;
    }

private:
    int year;
    int month;
    int day;
};

class Person
{
public:
    Person(){cout << "Person:无参构造函数" << endl;}
    Person(int id, string name, int score, int year, int month, int day)
    {
        cout << "Person:有参构造函数" << endl;
        this->id = id;
        this->name = name;
        this->score = score;

        this->mybirth.setBirthdayMsg(year, month, day);
    }

    ~Person()
    {
        cout << "Person:析构函数" << endl;
    }

    Person(const Person &obj)
    {
        cout << "Person:拷贝构造函数" << endl;
        this->id = obj.id;
        this->name = obj.name;
        this->score = obj.score;
    }

    void printMsg()
    {
        cout << this->id << ", ";
        cout << this->name << ", ";
        cout << this->score << ", ";
        cout << this->mybirth.getYear() << "/";
        cout << this->mybirth.getMonth() << "/";
        cout << this->mybirth.getDay() << endl;
    }

private:
    int id;
    string name;
    int score;
    //成员对象,将一个类的对象作为另一个类的成员变量
    Birthday mybirth;
};

void test1()
{
    //含有成员对象的构造和析构函数的调用顺序:
    //构造函数调用顺序:
    //   成员对象的构造 --> 当前对象的构造
    //析构函数的调用顺序:
    //   当前对象的析构 --> 成员对象的析构
    //Person p1;
    Person p1(1001, "张三", 90, 1999, 9, 19);
    p1.printMsg();
}

int main()
{
    test1();

    return 0;
}

注意输出的顺序

图片.png