条款03 尽可能使用const——47


指针常量和常量指针的分辨(从右往左读法)。
const在函数中的使用(函数返回类型、函数参数)。
令函数返回一个常量值,往往可以降低因客户错误而造成的以外,而又不至于放弃安全性和高效性。

const成员函数——49

将const实施于成员函数的目的, 是为了确认该成员函数可作用于const对象身上。这一类成员函数之所以重要,基于两个理由。第一,它们使class接口比较容易被理解。第二,它们使“操作const对象”成为可能。这对编写高效代码是个关键,因为如条款20所言,改善C++程序效率的一个根本方法是以通过引用常量(pass by reference-to-const)方式传递对象,而此技术可行的前提是,我们有const成员函数用来处理取得(并经修饰而成)的const对象。

bitwise constness和logical constness——51

bitwise const阵营的人相信,成员函数只有在不更改对象之任何成员变量(static除外)时才可以说是const。也就是说它不更改对象内的任何一个bit。这也是C++对常量性(constness)的定义。
但是有时情况并非如此,如下所示,TextBlock类中有一个所谓的const成员函数:

class CTextBlock{
public:
    ...
    char& operator[](std::size_t position) const{
    return pText[position];
    }
private:
    char* pText;
};

上述class不适当地将其operator[]声明为const成员函数,而该函数却返回一个reference指向对象内部值。因为,operator[]实现代码并不更改pText,所以编译器认为是对的。接下来会有什么后果:

const CTextBlock cctb("Hello");
char* pc=&cctb[0];
*pc='J';

上述代码没有任何错误,但是改变了这个对象的值,最终cctb保存的值变成"Jello"。
由此产生了logical constness拥护者,他们认为一个const成员函数可以修改它所处理的对象内的某些bits,但只有在客户端侦测不出的情况下才得如此。

mutable的用法——52

我们看下面一段代码:

class CTextBlock{
public:
    ...
    std::size_t length() const;
private:
    char* pText;
    std::szie_t textLength; //最近一次计算的文本区块长度
    bool lengthIsValid; //目前的长度是否有效
};
std::size_t CTextBlock::length() const{
    if(!lengthIsValid){
        textLength=std::strlen(pText); //错误
        lengthIsValid=true; //error!
    }
    return textLength;
}

上述代码中的length函数不能通过编译,因为修改了textLength和lengthIsValid数据,而这个函数有事const。如果想被修改,可利用一个与const相关的摆动场:mutable(可变的)。mutable释放掉non-static成员变量的bitwise constness约束:

class CTextBlock{
public:
    ...
    std::size_t length() const;
private:
    char* pText;
    mutable std::szie_t textLength; 
    mutable bool lengthIsValid; 
};
std::size_t CTextBlock::length() const{
    if(!lengthIsValid){
        textLength=std::strlen(pText); //ok
        lengthIsValid=true; //ok
    }
    return textLength;
}
在const和non-const成员函数中避免重复——53

这部分主要讲non-const成员函数使用const_cast和static_cast来调用const成员函数,使避免两个函数写太多重复的操作。
但经验告诉我们,这种强制转换类型并不推荐。

总结——56

(1)将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
(2)编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”(consceptual constness)。
(3)当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值