c++中的this指针

来源:互联网 发布:js 捕获异常 编辑:程序博客网 时间:2024/05/01 16:40

C++中的this指针

(1)       this指针是什么:

对于类,类的成员函数具有一个附加的隐含形参,即指向该类对象的一个指针。隐含形参命名为this,与调用成员函数的对象绑定在一起。成员函数不能定义this形参,而是由编译器隐含定义的。成员函数的函数体可以显示的使用this指针(访问数据成员),但是一般不必这么做。

编译器在编译的时候会自动加上this指针,比如:object.printfInfo();相当于object.printfInfo(&object);  这里的&object就是通过this指针引用的。

注意:由于this是对象所有,对于静态成员(成员函数和成员数据),是不存在this指针的。

(2)       何时使用this指针:this指针主要用于返回对整个对象的引用,比如拷贝构造函数(还有比如对于某些类希望提供连续操作,如myScreen.move(4,0).set(“#”);移动光标然后设置显示字符等),需要返回整个对象的引用,就需要用到this指针。在成员函数中使用this指针返回对调用该函数的对象的引用。还有一种情况需要用到this指针,就是如果类的成员函数的形参命名和类的数据成员命名一样的时候,必须用this指针对类的成员数据赋值,这是由作用域决定的,在类的成员函数内部,形参(局部变量)作用域覆盖了类的成员变量的作用域。

/*示例代码*/

#include <iostream>

using namespace std;

 

class Screen

{

public:

   Screen& move(int r,int c);  

   Screen& set(char x);

  

private:

   int r,c;

};

 

Screen& Screen::move(int r,int c)

{

   this->r=r;

   this->c=c;

   //do sth

  

   return *this;

}

 

Screen& Screen::set(char x)

{

   //do sth

   return *this;

}

 

int main()

{

   Screen scr=Screen();

   scr.move(1,4);

   scr.set('a');

  

   scr.move(2,4).set('a');      //连续使用

   return 0;

}

(3)       this指针的存在(this指针何时构建,何时清除):

一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。

this指针在对象开始执行成员函数之前构造,在成员函数执行结束清除。

(4)       *this含义:this就是一个指针,所以可以通过*this进行解引用来访问this指向的对象。

(5)       this相关的const主题:

在普通的非const成员函数中,this的类型是一个指向类类型的const指针。可以改变this所指向的值,但不能改变this所保存的地址。const成员函数中,this的类型是一个指向const类类型对象的const指针。既不能改变this所指向的对象,也不能改变this所保存的地址。

注意:不能从const成员函数返回指向类对象的普通引用。const成员函数只能返回*this作为一个const引用。

仔细理解上面红色部分内容。请仔细理解下面的例子的错误。

下面代码中display是一个const成员函数,由于const成员函数中this是一个指向const对象的const指针,所以*this是一个const引用,返回值必须定义为const Screen&,所以下面的代码会提示错误:error C2440: 'return' : cannot convert from 'const class Screen' to 'class Screen &' Conversion loses qualifiersvc6.0下错误提示)

display定义为 const Screen& display() const;才能编译通过。

/*示例代码*/

#include <iostream>

using namespace std;

 

class Screen

{

public:

   Screen();

 

   Screen& move(int r);        //移动

   Screen& set(char x);         //设置

 

   Screen& display() const;       //显示

 

  

private:

   int r;                  //索引位置

   char contents[100];    //内容

};

 

Screen::Screen()

{

   for(int i=0;i<100;i++)

            contents[i]='/0';

}

 

Screen& Screen::move(int r)

{

   this->r=r;

 

   return *this;

}

 

Screen& Screen::set(char x)

{

   //do sth

   contents[r]=x;

   return *this;

}

 

Screen& Screen::display() const

{

//         r=9;

 

   return *this;

}

 

 

 

 

int main()

{

   Screen scr=Screen();

 

   return 0;

}

上面的问题定义了const成员函数,但是存在一个问题,display方法返回的是const引用。如果希望myScreen.display().move(2).set(‘a’);这样使用,那么会出错,因为display返回的是const myScreen&类型,不能在const对象上调用非const成员函数(除非把move也定义为const成员,不过这样不符合设计的意图)。

/*示例代码*/

#include <iostream>

using namespace std;

 

class Screen

{

public:

   Screen();

 

   Screen& move(int r);        //移动

   Screen& set(char x);         //设置

 

   const Screen& display() const;       //显示

 

  

private:

   int r;                  //索引位置

   char contents[100];    //内容

};

 

Screen::Screen()

{

   for(int i=0;i<100;i++)

            contents[i]='/0';

}

 

Screen& Screen::move(int r)

{

//         this->r=r;

 

   return *this;

}

 

Screen& Screen::set(char x)

{

   //do sth

   contents[r]=x;

   return *this;

}

 

const Screen& Screen::display() const

{

//         r=9;

 

   return *this;

}

 

 

 

 

int main()

{

   Screen scr=Screen();

   scr.display();  //right

   scr.move(3);    //right

 

   //scr.display().move(4);    //error

 

   return 0;

}

为了解决这个问题,解决方法通过重载,即定义两个display操作,一个const的,一个非const的。const对象只能使用const成员,非const对象可以使用const或者非const成员,但是非constdisplay匹配更好,所以实际调用的是非const的。

/*示例代码*/

#include <iostream>

using namespace std;

 

class Screen

{

public:

   Screen();

 

   Screen& move(int r);        //移动

   Screen& set(char x);         //设置

 

   const Screen& display() const;   //constdisplay

   Screen& display();            //constdisplay

 

  

private:

   int r;                  //索引位置

   char contents[100];    //内容

};

 

Screen::Screen()

{

   for(int i=0;i<100;i++)

            contents[i]='/0';

}

 

Screen& Screen::move(int r)

{

//         this->r=r;

 

   return *this;

}

 

Screen& Screen::set(char x)

{

   //do sth

   contents[r]=x;

   return *this;

}

 

const Screen& Screen::display() const

{

//         r=9;

   cout<<"const display called"<<endl;

   return *this;

}

 

Screen& Screen::display()

{

   //do sth

   cout<<"none const display called"<<endl;

   return *this;

}

 

 

 

 

int main()

{

   Screen scr=Screen();

   scr.display();  //right:调用非constdisplay

   scr.move(3);    //right

 

   scr.display().move(4);    //right:调用非constdisplay

   const Screen test=Screen();

   test.display();     //right:调用constdisplay

 

   return 0;

}

(6)       一些可以参考的分析this指针的网址:

http://blog.csdn.net/starlee/archive/2008/01/24/2062586.aspx 浅析C++中的this指针

http://blog.csdn.net/feiyond/archive/2007/06/14/1652505.aspx C++ this指针的理解