首页 > 代码库 > this指针和 *this
this指针和 *this
我们都知道,类的成员函数有一个附加的隐形形参,即指向该类对象的this指针,它与调用成员函数的对象绑定在一起。那么,这个this指针究竟是什么样的指针呢?其解引用*this返回的又是怎样的一个对象呢?
首先,我们以《C++ Primer》书中的Screen类为例说明,这个类只是简单声明,有些成员函数的具体实现没有定义。不必关注成员函数的实现,只需要看它的形式即可。
//定义一个名为Screen的类型来表示计算机上的窗口 #include <iostream> #include <string> using namespace std; class Screen { public: //使用类型别名来简化类 typedef string::size_type index; //构造函数 Screen(index hght,index wdth,const string &cntnts=""): height(hght),width(wdth),cursor(0),contents(cntnts){} //返回光标的位置 index get_cursor() const{return cursor;}; //增加三个成员函数,返回*this Screen& move(index r,index c);//给定两个index值,将光标移至新位置 Screen& set(char);//将特定字符设置为特定值 const Screen& display(ostream &os) const;//输出内容 private: std::string contents;//窗口内容 index cursor;//光标当前停留的位置 index height,width;//窗口的高度和宽度 }; //给定两个index值,将光标移至新位置 Screen& Screen::move(index r,index c) { index row=r*width; cursor=row+c; return *this; } //将特定字符或光标指向的字符设置为特定值 Screen& Screen::set(char c) { contents[cursor]=c; return *this; } //输出内容 const Screen& Screen::display(ostream &os) const { os<<contents; return *this; } int main() { //根据屏幕的高度、宽度和内容的值来创建Screen Screen myscreen(5,6,"abcde\nfghij\nklmno\pqrst\nuvwxy"); myscreen.move(4,0).set('#').display(cout); cout<<endl; return 0; }
基本概念
- const指针——指针本身的值不可修改,只能指向指定位置的对象
其定义如下:
int errNumb = 0;
int *const curErr=&errNumb;//curErr是一个指向int型对象的const指针
可以改变const指针所指向的值,但不能改变const指针所保存的地址,如下:
*curErr=1;//curErr所指向的值变为1,即errNumb=1
++curErr;//错误,curErr是一个常量,不能改变
const指针在定义时必须初始化,一经初始化,则指针本身不可再修改,只能指向初始化时的对象。- 指向const对象的指针——只能读取对象,不能利用指针修改对象
其定义如下:
const double pi = 3.14;
const double *cptr = π//cptr是一个指向const对象pi的指针- 常(const)成员函数
在形参表后用const修饰的成员函数,表示只能读取类的数据成员,不能修改。如上例中的index get_cursor()const{return cursor;};- 常(const)对象
在定义类对象时用const修饰的对象,常对象只能调用类中的常成员函数,而普通的对象则没有此限制。如下例:
const Screen herscreen();//herscreen就是一个Screen类型的常对象
this指针
- this指针是指向类类型的const指针
调用成员函数时,隐藏的this指针被初始化为调用成员函数的对象的地址,可以改变this所指向的值,但不能改变this所保存的地址,即this指针只能指向该对象,不能指向别的对象。所以,无论在非const成员函数还是const成员函数中,this首先是一个指向类类型的const指针。在上例中,非const函数Screen& move(index r,index c)的this类型如下:
Screen *const this - const成员函数中的this指针——指向常(const)对象的const指针
在普通的非const成员函数中,this的类型就是一个指向类类型的const指针。
而在const成员函数中,因为不能通过this指针修改类的数据成员,只能读数据成员,故this的类型是一个指向常(const)类对象的const指针。既不能改变this所指向的对象,也不能改变this所保存的地址。在上例中,const成员函数 get_cursor() const的this的类型如下:
const Screen *constthis
返回*this——返回的是一个对象的引用
- 何时返回*this
当我们需要将一个对象作为整体引用而不是引用对象的一个成员是。最常见的情况就是在这样的函数中返回*this:
该函数返回对调用该函数的对象的引用。
如上例中的
myscreen.move(4,0).set(‘#‘);
等价于
myscreen.move(4,0);
myscreen.set(‘#‘); - 返回的对象引用是什么类型:常对象引用 or not?
在普通的非const成员函数中,*this返回的普通的对象引用。在上例中,非const成员函数move( )返回的就是一个普通的对象引用:<span style="color:#ff0000;">Screen&</span> move(index r,index c) { index row=r*width; cursor=row+c; <span style="color:#ff0000;">return *this;</span> }
而在const成员函数中,*this返回的是常(const)对象引用。在上例中,const成员函数display() const返回的就是一个常(const)对象的引用:<span style="color:#ff0000;">const Screen&</span> display(ostream &os) <span style="color:#ff0000;">const</span> { os<<contents; <span style="color:#ff0000;">return *this;</span> }
注意:
不能从const成员函数返回指向类对象的普通引用,而应该是const引用。const成员函数只能返回*this作为一个const引用。
Screen& display(ostream &os) const; //错误,const成员函数返回的应该是一个const对象引用
那么返回类型之间的区别又会导致什么结果呢?
我们知道,常(const)对象只能调用const成员函数,而普通对象既能调用const成员函数,又能调用非const成员函数。所以,我们可以判断以下调用是否正确?
mysceen.move(4,0).set(‘#‘); //正确,因为非const成员函数move()返回的是普通引用,可以调用一切成员函数
myscreen.move(4,0).display(cout);//正确
myscreen.display(cout).set(‘#‘); //错误,因为const成员函数display()返回的常对象引用,只能调用const成员函数,而set.()是非const成员函数
因此,我们可以确定,返回类型的不同对调用成员函数有了限制。
- 非const成员函数的this是一个指向类类型的const指针,可以改变this所指向的值,但不能改变this所保存的地址,即不能再指向别的对象。
const成员函数的this是一个指向常(const)类对象的const指针,既不能改变this所指向的对象的值,也不能改变this所保存的地址。 - 非const成员函数的*this返回的是普通引用,可以调用一切成员函数。
const成员函数的*this返回的是常(const)对象引用,只能调用const成员函数。
this指针和 *this
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。