浅谈this指针

先给出知码开门上到一道练习题:

定义一个Circle类,有数据成员radius(半径)、成员函数getCircumference()计算圆的周长,成员函数getArea()计算圆的面积。在主函数中定义圆对象,通过调用成员函数计算圆的周长和面积。提示:圆周率取值3.14。

后置代码:

int main()
{
	float radius;
	cin>>radius;
	Circle c(radius);
	cout<<"半径为"<<radius<<"的圆的周长为:"<<c.getCircumference()<<",面积为:"<<c.getArea()<<endl;
	return 0;
}

当时给出了这样的代码,但是在debug发现了一个问题。

给出的代码(纠正也在这上面,通过注释写出)

#include <iostream>
using namespace std;

class Circle{
private:
    float r;
public:
    Circle(float r){
        r=r;
    //更正:this->r=r;
    }
    float getCircumference(){ //周长
        return 2*3.14*r;
    }
    float getArea(){ //面积
        return 3.14*r*r;
    }
};

Xcode控制台输入输出:

6
半径为6的圆的周长为:0,面积为:0

更正之后的输入输出:

6
半径为6的圆的周长为:37.68,面积为:113.04

没想到少了一个this指针,结果竟然完全不正确。仔细回想,如果不加this指针,则是将自身的值重新赋给自身,自然没有任何意义(不明白为什么Xcode既不报Warning也不报Error)。

但是反过来,这个传说中的this指针又究竟是什么呢?

biaocheng.net给出了这样的解释:

this 是 C++ 中的一个关键字,也是一个 const 指针,它指向当前对象,通过它可以访问当前对象的所有成员。

我们在刚刚的代码中加入一个操作print_this,源代码如下:

    void print_this(){
        cout<<this<<endl;
    }

我们在刚刚的代码中,将main函数替换为下面的代码,创建两个不同的对象并观察运行情况。

    Circle c(1);
    c.print_this();
    Circle s(100);
    s.print_this();

程序在Xcode上的打印结果:

0x7fff5fbff718
0x7fff5fbff710
Program ended with exit code: 0

可以看到,this指针用于指向当前对象,对于不同的对象,所指向的地址并不相同。

biaocheng.net给出了对this指针本质的理解:

this 实际上是成员函数的一个形参,在调用成员函数时将对象的地址作为实参传递给 this。不过 this 这个形参是隐式的,它并不出现在代码中,而是在编译阶段由编译器默默地将它添加到参数列表中。

this 作为隐式形参,本质上是成员函数的局部变量,所以只能用在成员函数的内部,并且只有在通过对象调用成员函数时才给 this 赋值。

补充几点说明:

  • this 是 const 指针,它的值是不能被修改的,一切企图修改该指针的操作,如赋值、递增、递减等都是不允许的。
  • this 只能在成员函数内部使用,用在其他地方没有意义,也是非法的。
  • 只有当对象被创建后 this 才有意义,因此不能在 static 成员函数中使用。

参考文献:http://c.biancheng.net/cpp/biancheng/view/201.html

 

分享