《Effective C++》阅读笔记:条款03:尽可能使用const

关键字const用来定义常量,常量声明语句的形式为:

const 数据类型说明 常量名 = 常量值;

数据类型说明 const 常量名 = 常量值;

//例如,声明圆周率PI为一个const,注意,声明为const的变量一定要赋予初值

const float PI = 3.141596;

const与指针

const与指针结合起来使用的时候,我们经常都会被搞得晕头转向,常量指针,指针常量,究竟是指针不变,还是指向的内容不变,下面看两个例子:

const char* p = "Hello World";  //常量指针,指向常量的指针
char* const p = "Hello World";  //指针常量,指针本身指向的地址不能够改变

这里可以通过下面这条准则来进行记忆:

如果关键字const出现在星号左边,表示被指示物是常量,如果出现在星号右边,做表示指针自身是常量,如果出现在星号的两边,则表示被指物两者都是常量。

const与STL

STL的迭代器就像是一个T*的指针,T* const表示的是指针的位置不能改变,但是其指向的内容可以改变,通过const_iterator来模拟const T*,表示指针可以改变,指向的内容不能改变:


std:vector<int> vec;
const  std::vector<int>::iterator iter = vec.begin();   //iter的作用相当于是T* const
iter = 10;  //没问题,更改iter所指向的值
++iter;     //错误,
std::vector<int>::const_iterator cIter = vec.begin();   //相当于是const T*
*cIter = 10;    //错误,常量指针无法修改指向的值
cIter++;        //没问题

在真实程序中,大多数const的用法是:passed by pointer-to-const 或 passed by reference-to-const

当成员函数是const的时候,有两个流行的概念:

  • Bitwise const:成员函数只有在不改变任何成员变量时才可以说是const
  • Logical const:一个const成员函数可以修改它所处理的对象内的某些bits,但只有在客户端检测不出来的情况下才得如此

在某些情况下,可以用logical const,但是编译器不同意,因为它仍然坚持bitwise const,这个时候可以利用C++的一个与const相关的摆动场:mutable(可变性),mutable释放掉non-static成员变量的bitwise constness约束:

class CTextBlock {
publicstd::size_t length() const;
private:
    mutable std::size_t textLength;
    mutable bool lengthIsVaild;
};

std::size_t CTextBlock::length() const {
    if(!lengthIsVaild) {
        textLength = std::strlen(pText);
        lengthIsVaild = true;
    }
    return textLength;
}

常量性转除(casting away constness)

为了避免冗余,可以使用non-const operator[]调用其const兄弟是一个避免代码重复的安全做法,即使过程中需要一个转型动作:

class TextBlock {
public:
    const char& operator[] (std::size_t position) const {
        …
        …
        …
        return text[position];
    }
    char& operator[] (std::size_t position) {
        return const_cast<char&> {  //将op[]返回值的const转除
                static_cast<const TextBlock&>(*this)    //为*this加上const,调用const op[]
                [position]
            };
    }
};

在这里,首先将*this从其原始类型TextBlock&转型为const TextBlock&,添加了const,接下来再使用const_cast去除掉const
但是const成员函数调用non-const成员函数”是一种错误的行为,因为在约定不改变const成员函数里面有non-const,违背了logical const的准则,如果非要这样做的话,可以使用const_cast去掉*this身上的const性质

请记住

  • 将某些东西声明为const可帮助编译器侦测出错误用法,const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
  • 编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”(conceptual constness)
  • constnon-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值