《Effective C++》读书笔记之const高效使用

来源:互联网 发布:static php 编辑:程序博客网 时间:2024/04/30 08:18

                                                                                                                        By Ryui Liu 2011/11/26

    C++const关键字允许你指定一个语义约束即指定这是一个“不能被改动”的对象,而编译器会强制实施这项约束。当你确实不希望某值保持不变时,你就该确实的说出来,这样编译器就可以帮助你确保这个值不被改变。

     const可以在class外部修饰globalnamespace作用域中的常量,可以修饰文件、函数、或区块作用域中被static声明的对象,可以修饰classes内部的staticnon-static成员变量,也可以修饰常量指针、指针常量、指向常量的指针常量;const最有威力的用法还是在函数声明时,可以和函数的返回值,各个参数,函数自身产生关联。

     const修饰变量时,如果const关键字出现在星号的左边,表示被指物是常量(没有星号时(即非指针变量)也适用),如果出现在星号的右边,则表示指针自身是常量,如果在星号两边都出现,则被指物和指针两者都是常量。

      const int i = 10

      char greeting [] = "hello world";

      char greeting2[] = "qu world";

      const char *p  = greeting; 

      char const *q  = greeting;  // pq都是常量指针

      char * const cq = greeeting; // cq为指针常量,不能改变它的指向

      *p = "aaaa";// error

       P = greeting2; //ok

       cq = greeting2; // error

       *cq ="aaaaa"; //ok 

      const char* const pq = greeting; //pq是指向常量的指针常量  

STL跌代器iterator 是普通指针,如果在其前面加上const修饰时,则该指针不能被改变,既迭代器不能改变,而const_iterator是一个指向常量的指针。例如:

      std::vector<int > vec;

      const std::vector<int>::iterator iter = vec.begin();

        *vec = 10 ;//ok  

        ++vec;  // error      

      std::vector<int>::const_iterator cIter = vec.begin();

         *vec = 10;//error

         ++vec;  //ok

     

     const修饰函数时,可以给参数加上const不希望修改参数的值,也可以给返回值加上const不希望无意中改变返回值。例如:

     class  aa.....;

     const  aa operator*(const aa& a1,const aa& a2);

此处则不希望改变operator *的返回值,假如一个混混沌沌的程序员写出ifa*b = c), 编译器给他错误提示了;如果没有加上const,或许他会抓狂的。

    

     在c++面向对象编程中,常用const来修饰类的成员函数,这样做是为了确认该成员函数可以作用于const对象身上。这样做有两个重要理由:第一、它们使class接口比较容易理解,得知哪个函数可以改动对象内容而哪个函数不可以,例如常见的get/set函数;第二、它们使“操作const对象”成为可能,这对编写高效代码是个关键。

需要提示的是:两个成员函数如果只有常量性不同即一个有const修饰,另一个没有,可以被重载。

const char& operator[]std::size_t positionconst {return ...}; //operator [] for const对象

char &operator[] (std::size_t position)(return ...);//operator[] for non-const 对象。

众所周知,我们在const成员函数中不能修改成员变量,但当需要修改时就需要另外一个关键字---mutable.    

例如

class MutableTest

{
   public:
     MutableTest();

       ~MutableTest();
      void Output() const;
     int GetOutputTimes() const;
   private:
     mutable int m_iTimes;
 };
MutableTest::MutableTest()
{
 m_iTimes = 0;
}
MutableTest::~MutableTest()
{}
void MutableTest::Output() const
{
 cout << "Output for test!" << endl;
 m_iTimes++;

int MutableTest::GetOutputTimes() const
{
 return m_iTimes;
}
在这个例子中,将Output函数修饰为const,却希望记录输出的次数,这时就需要改变m_iTimes的值,这个时候就需要mutable关键字来突破const关键字的限制了:m_iTimes在常成员函数中也可以被改变。

    总结:const可以被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体,将某些东西声明为const可以帮助编译器侦测错误用法。当需要在const的成员函数内部修改成员变量时,可以求助于mutable关键字。

原创粉丝点击