第十二章 类
关于C++的几篇博客,参考人民邮电出版社的《C++ Primer 中文版》一书。
本章节介绍类的隐含this指针和mutable可变数据成员。
第二节 隐含的this指针和mutable可变数据成员
类的成员函数都具有一个附加的隐含形参,就是this指针,它指向所在类对象。
首先上个例子,然后根据例子了解this指针。
// 例1
class Screen {
public:
typedef std::string::size_type index;
Screen& move( index r, index c);
Screen& set( char );
Screen& display( std::ostream &os ) {
do_display( os );
return *this;
}
const Screen& display( std::ostream &os ) const {
do_display( os );
return *this;
}
private:
std::string contents;
index height;
index width;
void do_display( std::ostream &os ) const {
os << contents;
}
};
Screen& Screen::set( char c )
{
contents[cursor] = c;
return *this;
}
Screen& Screen::move( index r, index c )
{
index row = r*width;
cursor = row+c;
return *this;
}
一、必须用this指针的情况:
成员函数可以显式使用this指针,但不必须。
那么我们只需要知道什么时候必须得用呢?当我们有必须使用指向类对象的指针或引用的理由时,就是必须得用的时候了。
比如,当成员函数的返回类型是所在类类型的指针或引用,且指向所在的对象时,就必须返回this了,这样方便其他成员函数被连续调用,如:
myScreen.move( 4, 0 ).set( '#' ); // move cursor to given position, and set that character
上面的执行语句等价于:
myScreen.move( 4, 0 );
myScreen.set( '#' );
见例1的set和move函数定义部分Line24~34(注意:返回类型之所以不能设置为Screen而是要设置成Screen&或Screen*,是因为我们上一篇博客最后提到过的,类定义体内不能定义自身类型的数据成员。)
二、可变数据成员mutable
class Screen {
private:
mutable int access_str;
}
我们有时希望类的数据成员是可以被改变的,那么定义时类型名前加mutable关键字就可以定义类的可变数据成员。
这样,mutable数据成员永远都不能为const,即便是在const成员函数中,甚至当它是const对象的成员时,都可以被修改。
三、const成员函数及this指针
1、如果在非const成员函数中,返回this指针,则this所指向的对象可以被改变,但this保存的地址不可修改(当然了,这是指针的属性)。
2、如果在const成员函数中,返回this指针,则this所指向的对象内容不可修改,且this保存的地址也不可改,那么也就是说this指向的是一个const对象。
综上,const成员函数只能返回const的this指针。
3、那么,这样就存在一个问题,如果我想在调用const成员函数返回的指针上,继续做修改数据成员的操作,那么就是不可实现的了。
要解决这个问题,自然就想到函数的重载了。
4、const成员函数的重载
const成员函数的重载,请参看本章节例1的Line7~14。
重载以后,const的Screen对象将会自动调用const的成员函数display;非const的对象两种成员函数都可以使用,当然最好是用非const的。
// 例2
Screen myScreen;
const Screen blank;
myScreen.display(cout); // 调用非const的display函数
myScreen.set('#').display(cout); // 调用非const的display函数
blank.display(cout); // 调用const的display函数