当我们调用一个类对象的时候,就会有一个this指针与调用成员函数的对象绑定在一起。虽然成员函数可以显式的使用这个指针,但是一般在什么时候使用呢?
当我们需要使用这个类的整体而不是其中的某个成员时,就需要this指针了。最常见的情况,就是一个函数返回调用该函数对象的引用:
char Screen::get(index n,index c)const
{
index row = n * width;
return contents[row + c];
}
inline Screen::index Screen::get_cursor()const
{
return cursor;
}
Screen& Screen::set(char c)
{
contents[cursor] = c;
return *this;
}
Screen& Screen::move(index r,index c)
{
if(r >= height || c >= width)
{
cerr<<"invalidate row or column"<<endl;
throw EXIT_FAILURE;
}
index row = r * width;
cursor = row + c;
return *this;
}
这样的话,就可以这样调用函数了:这样的话,就可以这样调用函数了:这样的话,就可以这样调用函数了:
myScreen.move(4,5).set('#');
有一点需要特别留心,对于普通函数,this指针是一个指向类类型的const指针(这个指针始终指向调用成员函数的类,但是这个类的成员是可以修改的),但如果这个函数是const函数,那么那么这个指针是指向const类类型的const指针:既不能改变指向,也不能改变这个类的成员的大小。
这就出现了一个问题,比如我们定义了一个display函数来显示内容,按理说,这个函数时const函数,但是如果这样定义,那么如果返回它的指针就是指向const类类型的const指针,那么如果我们按照前面的方式使用,就会出错:
myScreen.display(cout).set('*');
因为函数的返回值是指向const类类型的const指针,不能调用非const函数。
一种比较好的解决方法,就是定义display的重载函数,当我们单独使用时,调用的是const版本,否则调用的是非const版本。
Screen& Screen::display(ostream &os)
{
do_display(os);
return *this;
}
const Screen& Screen::display(ostream &os)const
{
do_display(os);
return *this;
}
void Screen::do_display(ostream& os)const
{
string::size_type index = 0;
while(index != contents.size())
{
os<<contents[index];
if(((index + 1) % width )== 0)
{
os<<'\n';
}
++index;
}
}
这两个函数仅在函数类型上有差别,所以我单独定义了一个do_display函数来完成函数的实际功能,这样做的好处其实很多:
1.这样不必编写重复的代码。
2.假如我们要修改显示的具体操作,只用修改do_display一处就可以了。尤其是,在do_display加入一些开发阶段经常使用的调试信息,当最终版本形成时,只用在这一个函数里删除调试信息即可。
3.如果我们把do_display定义成内联函数,那么与重复的写这些代码相比,这个函数调用过程并不会增加任何性能的开销。