• this指针


    ----------------siwuxie095

       

       

       

       

       

       

       

       

       

    this 指针

       

       

    看如下实例:

       

    定义一个 Array 类,数据成员为:len

       

       

       

       

    通过观察,可以发现:参数和数据成员并不同名

       

       

       

       

    看如下实例:

       

       

       

    如果同名,有如下问题:

    构造函数中,如果这样写,不管是人类还是计算机,都无法判断究竟是

    将参数赋值给数据成员了,还是将数据成员赋值给参数了

       

    setLen() 函数中同理 …

       

    既然计算机无法判断,就会把这样的赋值认为是错误的

       

    可见:主要问题在于编译器无法分辨哪个是作为参数的 len,

    哪个是作为数据成员的 len

       

    这就是说,迫切的需要一种技术,这种技术要么可以标记出

    参数,要么可以标记出数据成员,这种技术正是 this 指针

       

       

       

    this 指针,即 指向对象自身数据的指针

       

    如果使用 Array 类实例化一个对象 arr1,this 指针就相当于是给 arr1 取地址,

    即 this 是 arr1 的地址,如果再实例化一个对象 arr2,那么 this 指针此时就是

    arr2 的地址

       

       

       

       

    在内存空间中的表示:

       

       

       

    this 如果写在 arr1 中,就是 arr1 的地址,如果写在 arr2 中,就是 arr2 的地址

       

    可见:this 要表达什么意思取决于它放在什么位置,通过 this 指针可以访问到它

    表达的对象自身的任何数据

       

       

       

    从另一个角度来说,就可以标记出它自身的数据成员,应用到

    代码中就可以写成这样:

       

    「参数和数据成员同名时,计算机就不会再疑惑,也能够正常的编译通过」

       

       

       

       

    继续观察之前的例子,难道大家没有对成员函数中直接去访问数据成员

    这种做法产生过怀疑吗?

       

       

       

       

       

       

    回顾对象结构的实例:

       

    car1、car2、car3 都有自己的数据成员,但成员函数却只有一份,

    这份成员函数写在代码区,三个对象都可以各自访问代码区中的成

    员函数,而且访问时也不会出任何的问题,在成员函数被调用的时

    候,也各自调用到了每一个对象的数据成员,并且没有出现混乱

       

       

       

       

    那么问题来了:既然函数的逻辑代码都是以二进制的形式存储在代

    码区,参数中也没有数据成员,那么在调用数据成员,尤其是存在

    多个对象时,函数如何确定该调用哪个对象的数据成员呢?

       

       

       

       

    要解决这个问题,也归功于 this 指针,看如下实例:

       

       

       

    不难发现,每一个成员函数的参数列表中都多出了一个 this 指针,而

    有了这样一个 this 指针,前面的问题也就迎刃而解了

       

       

       

    我们可以设想一下,当实例化对象并使用这些成员函数时,this 指针

    就代表着这个对象本身的地址

       

       

    当实例化 arr1 时,构造函数中传入参数 this,当执行给 len 赋值

    10 的操作时,相当于是在执行 this 的 len 赋值 10 的操作,因为

    this 就指的是 arr1,所以用 this 指向 len 时,其实指向的是 arr1

    的 len,也就不会给其他的对象赋错值了

       

    同理,如果用 arr1 调用 getLen() 时,也传入了参数 this,当调用

    return len 时,相当于调用 return this->len,也就是 arr1 的 len

       

    当实例化 arr2 时,此时的 this 就已经是 arr2 的地址了 …

       

    从而使 arr1 和 arr2 在同时调用这些成员函数时,不会产生对象错

    乱的情况

       

       

       

    因为每次调用成员函数,都需要 this 指针,所以 C++ 的编译器

    干脆就替我们干了这件事,于是摆在我们面前的成员函数就成了

    现在的样子:不加 this

       

       

       

       

    其实在编译时,编译器自动的为每一个成员函数的参数列表都加了

    一个 this 指针

       

    因为编译器为我们干了这些事情,所以自定义时就不必要再加 this

    指针这个参数,使用的时候也完全可以当做没这回事儿

       

       

       

       

       

       

    程序 1

       

    Array.h:

       

    class Array

    {

    public:

    Array(int len);

    ~Array();

    void setLen(int len);

    int getLen();

    void printInfo();

    private:

    int len;

    };

       

       

       

    Array.cpp:

       

    #include "Array.h"

       

    Array::Array(int len)

    {

    //容易混淆的地方用this指针标记(不标记的话编译器就不知道

    //是参数给数据成员赋值还是数据成员给参数赋值)

    this->len = len;

    }

       

    Array::~Array()

    {

       

    }

       

    void Array::setLen(int len)

    {

    this->len = len;

    }

       

    int Array::getLen()

    {

    return len;

    }

       

    void Array::printInfo()

    {

       

    }

       

       

       

    main.cpp:

       

    #include <stdlib.h>

    #include "Array.h"

    #include <iostream>

    using namespace std;

       

       

    int main(void)

    {

    Array arr1(5);

    cout << arr1.getLen() << endl;

    system("pause");

    return 0;

    }

       

       

       

       

       

       

    程序 2:

       

    Array.h:

       

    class Array

    {

    public:

    Array(int len);

    ~Array();

    Array* setLen(int len);

    int getLen();

    Array& printInfo();

    private:

    int len;

    };

       

       

       

    Array.cpp:

       

    #include "Array.h"

    #include <iostream>

    using namespace std;

       

       

    Array::Array(int len)

    {

    //在容易混淆的地方用this指针标记

    this->len = len;

    }

       

    Array::~Array()

    {

       

    }

       

    Array* Array::setLen(int len)

    {

    this->len = len;

    //return出去的是arr1this指针

    return this;

    }

       

    int Array::getLen()

    {

    return len;

    }

       

    Array& Array::printInfo()

    {

       

    cout << "len=" << len << endl;

    return *this;//return出去的是arr1的引用

    }

       

    //Array Array::printInfo()

    //{

    //

    // cout << "len=" << len << endl;

    // return *this;//return出去的是新的临时对象

    //}

       

       

       

    main.cpp:

       

    #include <stdlib.h>

    #include "Array.h"

    using namespace std;

       

    //this 指针的本质就是其所在对象的地址

    int main(void)

    {

    Array arr1(10);

    //根据返回值类型的不同选择不同的操作符 . ->

    arr1.printInfo().setLen(5)->printInfo();

    system("pause");

    return 0;

    }

       

    //printInfo() 前面是Array& setLen(5)

    //

    //arr1.printInfo().setLen(5);

    //arr1.printInfo();

    //

    //最终打印出一个10 一个5

       

    //如果printInfo()前面不是Array& 而是Array

    //那么return出来的就是一个新的临时对象(是另外的对象,并不是arr1)

    //setLen(5)

    //

    //arr1.printInfo().setLen(5);

    //arr1.printInfo();

    //

    //就会打印出两个10 而不是一个10 一个5

       

    //Array& Array* 效果一样只不过一个是指针一个是引用罢了

    //这便是Array Array& Array* 的不同与妙用了

       

    //假如我在printInfo()函数中把原来的cout换成 cout<<this<<endl;

    //即打印出this指针的地址同时在main()函数中 cout<<&arr1<<endl;

    //这样就可以清晰的看到this指针指向的是对象的地址(this指针的本质)

       

       

       

       

       

       

       

       

       

    【made by siwuxie095】

  • 相关阅读:
    10-2[RF] OOB validation
    5.css背景以及书写位置
    4.css基础
    3.表单form
    2.表格
    1.html基础
    正则表达式
    协程
    7.树与树算法
    6.排序与二分查找
  • 原文地址:https://www.cnblogs.com/siwuxie095/p/6798350.html
Copyright © 2020-2023  润新知