1.對於const修飾的成員函數分為兩種觀點: logic constness and bitwise constness.
bitwise constness 的觀點就是說 :“它不更改對象的任一bit”, 這樣一來 , 編譯器只要成員變量有賦值的行為即可,這是對只讀性的定義,因此,const 成員函數不可以更改對象中任一non- static 成員變量。
eg1:
class TextBlock
{
public:
............
char& operator [] (std::size_t position) ;
const char& operator [] (std::size_t position) const ;
private:
std::string text ;
} ;
TextBlock bt("Jack") ;
std::cout<<bt[0] ; //true , read a non-const TextBlock
bt[0] = 'T' ; //true , write a non-const TextBlock
const TextBlock cbt("Rose") ;
std::cout<<cbt[0] ; //true , read a const TextBlock
cbt[0] = 'L' ; //false , cannot write a const TextBlock !!
char *ptr = &ctb[0] ;
*ptr = 'T' ; //true , not change the adress of ctb[0] , but the content has changed!!
而logical constness的觀點是可以改變對象內的某些bits ,例如eg1中的*ptr = 'T' ; 這樣還是讓ctb中的pText 值改變了!!
若類的常成員函數有non-const 數據成員,並且要進行賦值操作, 那只能用mutable 來修飾non-const 數據成員了
eg2:
class TextBlock
{
public:
TextBlock(char * str = "\0" ) : pText(str) , textLength(0) , lengthIsValid(false)
{}
std::size_t length() const ;
private:
std::size_t textLength ;
bool lengthIsValid ;
} ;
std::size_t TextBlock::length() const
{
if(!lengthIsValid)
{
textLength = std::strlen(pText) ;
lengthIsValid = true ;
}
return textLength ;
}
2.在const 與non-const 成員函數避免重復,這時候需要進行解除const的只讀性和加上const 的只讀性。
eg3:
class TextBlock
{
public:
TextBlock(string name = "\0") ;
const char& operator [] (std::size_t position ) const ; //常成員函數
char& operator [](std::size_t position) ; //普通成員函數
private:
std::string m_Name ;
} ;
TextBlock::TextBlock(string name):m_Name(name)
{}
const char& TextBlock::operator [] (std::size_t position) const
{
if(position >= m_Name.length() || position < 0) //邊界檢查
{
throw 0 ; //拋出異常
}
else
{
return m_Name[position] ;
}
}
//利用普通成員函數去調用常成員函數
char& TextBlock::operator[] (std::size_t position)
{
//static_cast<const TextBlock&>類型轉換非常對象變成常對象,以此調用常成員函數
//cosnt_cast是把常operator[]的返回常量去掉
//若不這樣進行兩次轉換,會出現無限的遞歸調用non-const operator[] 函數
return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]) ;
} www.2cto.com