当前位置 主页 > 网站技术 > 代码类 >

    C++中this指针的理解与作用详解

    栏目:代码类 时间:2019-12-01 12:08

    01 C++ 程序到 C 程序的翻译

    要想理解 C++ 的 this 指针,我们先把下面的 C++ 代码转换成 C 的代码

    class Car 
    {
    public:
     int m_price;   // 成员变量
     void SetPrice(int p) // 成员函数
     {
      m_price = p; 
     }
    };
    
    int main()
    {
     Car car;
     car.SetPrice(20000); // 给car对象m_price成员变量赋值
     
     return 0;
    }

    C 语言是没有类定义的class关键词,但是有跟class类似的定义,那就是结构体struct。

    m_price变量是Car类的成员变量,那么我们可以把Car类和成员变量翻译成如下的 C 代码:

    // 结构体Car
    struct Car
    {
     // price变量是属于Car结构体这个域里的变量
     int price; 
    };

    SetPrice函数是Car类的成员函数,但是 C 程序里是没有成员函数这种概念的,所以只能把成员函数翻译成全局的函数:

    // 参数1:结构体Car的指针
    // 参数2:要设置的价格变量
    void SetPrice(struct Car* this, int p)
    { 
     this->price = p; // 将传入的Car结构体的price变量赋值
    }

    为什么要加个 this 的指针呢?我们继续往下看。

    在这里我们把上面main函数下面的 C++ 程序翻译 C 程序是这样的:

    int main() 
    {
     struct Car car;
     SetPrice( &car, 20000);
     return 0;
    }

    所以最终把上述的 C++程序 转换成C 程序的代码如下:

    struct Car
    {
     int price; 
    };
    
    
    void SetPrice(struct Car* this, int p)
    { 
     this->price = p; 
    }
    
    int main() 
    {
     struct Car car;
     SetPrice( &car, 20000); // 给car结构体的price变量赋值
     return 0;
    }

    02 this指针的作用

    其作用就是指向成员函数所作用的对象,

    所以非静态成员函数中可以直接使用 this 来代表指向该函数作用的对象的指针。

    #include <iostream>
    
    class Car 
    {
    public:
     int m_price;
     
     void PrintPrice()
     {
      std::cout << m_price << std::endl; 
     }
     
     void SetPrice(int p)
     {
      this->m_price = p; // 等价于 m_price = p;
      this->PrintPrice();// 等价于 PrintPrice();
     }
     
     Car GetCar()
     {
      return *this; // 返回该函数作用的对象
     }
    };
    
    int main(void)
    {
     Car car1, car2;
     car1.SetPrice(20000);
     
     // GetCar()成员函数返回所作用的car1对象,所把返回的car1赋值给了car2
     car2 = car1.GetCar(); 
     car2.PrintPrice(); 
     
     return 0;
    }

    输出结果:

    20000
    20000

    接下来我们下面的代码,你觉得输出结果是什么呢?会出错吗?

    class A
    {
     int i;
     public:
     void Hello() { cout << "hello" << endl; }
    };
    
    int main()
    {
     A * p = NULL;
     p->Hello(); //结果会怎样?
    }

    答案是正常输出hello,你可能会好奇明明 p 指针是空的,不应该是会程序奔溃吗?别着急,我们先把上面的代码转换C程序,就能理解为什么能正常运行了。

    void Hello() { cout << "hello" << endl; } 
    # 成员函数相当于如下形式:
    void Hello(A * this ) { cout << "hello" << endl; }
    
    p->Hello(); 
    # 执行Hello()形式相当于:
    Hello(p);

    所以,实际上每个成员函数的第一个参数默认都有个指向对象的 this 指针,上述情况下如果该指向的对象是空,相当于成员函数的第一个参数是NULL,那么只要成员函数没有使用到成员变量,也是可以正常执行。