C++ 的 this 指针详解

C++ 的 this 指针

thisC++ 中的一个关键字,也是一个 const 指针,它指向当前对象地址(换句话说,其值为 &object),通过它可以访问当前对象的所有成员。

1. this 工作原理

我们知道类 class 是对象 object 的模板,所以在创建对象之前需要先定义类,类的定义包含属性(变量)和方法的定义。

类定义好后我们就可以通过类来创建多个实例对象,每个对象都有各自的实例属性(实例变量),但是非内联成员函数(non-inline member function)只会诞生一份函数实例(换句话说每个对象需要共用同一个方法来操作实例属性)。在有多个实例对象访问同一个函数时,函数如何知道该操作哪个对象的属性?此时就需要 this 指针。

编译器会隐式地传递 this 指针,this 指针如同一个句柄,此时方法将根据句柄来确定需要操作哪个对象的属性。调用静态方法时,则不会隐式地传递 this 指针,因为静态函数不与类实例对象相关联,即不属于某个对象拥有而由所有实例对象共享。

2. 实例理解

现在我们通过结合程序来说明并理解上一节所描述的原理,这里我们定义了类 Hello,其中包含三个实例属性,以及一个使用属性的方法 setValue,以 Hello 为模板创建了三个对象 object1, object2, object3

#include <iostream>

using std::cout;

class Hello {
    
    
public:
    int a;
    int b;
    int c;

    Hello(int _a, int _b, int _c) {
    
    
        a = _a;
        b = _b;
        c = _c;
    }

    void setValue(int _a, int _b, int _c) {
    
    
        a = _a;
        b = _b;
        c = _c;
    }

    int getSum() {
    
    
        return (a + b + c);
    }
};

int main()
{
    
    
    Hello object1(10, 20, 30);
    Hello object2(20, 20, 10);
    Hello object3(10, 10, 10);

    cout << "Hello";

    return 0;
}

将类 Hello 实例化时会根据类中定义的属性来创建每个对象各自的属性,确保各自数据完整性 object1::(a, b, c)object2::(a, b, c)object3::(a, b, c) 这一步就是将属性存放至每个对象各自的内存空间下。但是方法 setValue 则不会根据对象来创建多个,意味着 object1object2object3 需要共用同一个方法 setValue 来修改他们的实例属性。

为了保证方法 setValue 能够修改对象对应的属性,编译器隐式的向方法内传递 this 指针,this 指针指向的是当前对象的地址(注意 this 是指针类型,在 C/C++ 中要用 -> 运算符来访问成员)。

#include <iostream>

using std::cout;

class Hello {
    
    
public:
    int a;
    int b;
    int c;

    Hello(int _a, int _b, int _c) {
    
    
        this->a = _a;
        this->b = _b;
        this->c = _c;
    }

    void setValue(int _a, int _b, int _c) {
    
    
        this->a = _a;
        this->b = _b;
        this->c = _c;
    }

    int getSum() {
    
    
        return (this->a + this->b + this->c);
    }
};

int main()
{
    
    
    Hello object1(10, 20, 30);
    Hello object2(20, 20, 10);
    Hello object3(10, 10, 10);

    cout << "Hello";

    return 0;
}

object1 访问 setValuethis 表示 (Hello *)&object1,当 object2 访问 setValuethis 表示 (Hello *)&object2,当 object3 访问 setValuethis 表示 (Hello *)&object3,如下程序所示(注意:下面程序不能运行,只是用于说明 this 指针的本质原理)。

#include <iostream>

using std::cout;

class Hello {
    
    
public:
    int a;
    int b;
    int c;

    Hello(int _a, int _b, int _c) {
    
    
        ((Hello*)&object1)->a = _a;
        ((Hello*)&object1)->b = _b;
        ((Hello*)&object1)->c = _c;
    }

    void setValue(int _a, int _b, int _c) {
    
    
        ((Hello*)&object1)->a = _a;
        ((Hello*)&object1)->b = _b;
        ((Hello*)&object1)->c = _c;
    }

    int getSum() {
    
    
        return (((Hello*)&object1)->a + ((Hello*)&object1)->b + ((Hello*)&object1)->c);
    }
};

int main()
{
    
    
    Hello object1(10, 20, 30);
    Hello object2(20, 20, 10);
    Hello object3(10, 10, 10);

    cout << "Hello";

    return 0;
}

3. this 使用场景

在一个对象的某个成员函数中需要返回对象本身时可以 return *this; 来将对象返回。

class Hello {
    
    
public:
    int a;
    int b;
    int c;

    Hello & getObject() {
    
    
        return *this;
    }
};

当对象的实例属性与对象成员函数形参或局部变量相同时,如果需要访问或给对象的实例属性复制则需要使用 this 指针进行访问 this->a = a,否则 a = a 访问的将是成员函数的形参或局部变量。

class Hello {
    
    
public:
    int a;
    int b;
    int c;

    Hello(int a, int b, int c) {
    
    
        this->a = a;
        this->b = b;
        this->c = c;
    }
};

猜你喜欢

转载自blog.csdn.net/jf_52001760/article/details/128533398