第十二章 類
關于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函數