Effective C++笔记之二const_and_non-const 修饰的成员函数

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]) ;




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值