码迷,mamicode.com
首页 > 编程语言 > 详细

C++中const作用

时间:2015-04-23 21:32:54      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

 1.   代替#define。   
    
  讲到用const来代替#define,为什么要这样做呢,当然是const比#define更好啦,一个很明显区别就是const有数据类型,可以进行类型安全检查,而#define只是简单的替换,并这个功能。所以我们就尽量使用   
    
            const   double   pi   =   3.1415926;   
    
  来代替这样的语句:   
    
            #define   pi   3.1415926;//最好用const来定义   
    
  而且#define的定义在进入编译器前会被替换掉,这样,当涉及到这个常量的编译错误时,报告是不是pi而是3.1415926这个常量,这样就带来的调试上的麻烦。   
    
  用cosnt来代替#define还有一个好处就是减少不必要的内存分配,例如:   
    
          #define   PI   3.1415926                   //常量宏   
    
          const   doulbe     Pi=3.1415926;     //此时并未将Pi放入ROM中   
    
          ......   
    
          double   i=Pi;                               //此时为Pi分配内存,以后不再分配!   
    
          double   I=PI;                               //编译期间进行宏替换,分配内存   
    
          double   j=Pi;                               //没有内存分配   
    
          double   J=PI;                               //再进行宏替换,又一次分配内存!   
    
  const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝换,又一次分配内存!   
    
  2.       使某个对象(变量)、值,指针,引用不能被修改。   
    
            这一点是大家最常见,用它来定义常量,使之具有不可变性。   
    
  对于用来修饰对象(变量),非常好理解,也是经常使用const的作用之一。但对于指针,可能就不好那好理解了,具体可以看以下代码:
    
                const   int   p                         //   相当于常量p

       int   const   p                         //   同上

                const   int   *a                        //   意味着a是一个指向常整型数的指针(不能通过*p来改变指向的变量的值,但是改变指针的指向,此最常见于函数的参数,当你只引用传递进来的指针所指向的值的时候加上const修饰符,程序中修改的编译就不通过,可以减少bug)

                int   * const  a                        //    表示a是一个指向整型数的常指针(可以修改指向的变量的值,但是不能改变指针的指向)

                int   const *  const   a              //   表示a是一个指向常整型数的常指针(即不可通过*p修改变量的值,也不可以改变指针的指向)

          总结:可以这样来记忆,const在谁前边,即const修饰谁,谁不可变。读的时候谁在前先读谁,如第3个, 读作常量指针, 第4个,读作指针常量      
    
  3.       使类的静态对象在类内部可以初始化   
    
  当我们要在类的内部定义某个常量时,就可能用const来修饰,否则的话,就不能初始化,看看下面的代码   
    
  class   print   
    
  {   
    
            private:   
    
                                //不能写成static   int   count   =   10;   
    
  static   const   int   count   =   10;   
    
  string   info[count];   
    
  };   
    
  const   int   print::count;   
    
                    当然出也可以通过类构造函数的初始化成员列表来初始化cosnt常量:   
    
                                class   A   
    
                    {   
    
                                public:   
    
                                                              A(int   i=0):count(i)   {}   
    
                                  private:   
    
                                                            const   int   count;   
    
                      };   
    
    
  4.       修饰函数参数和返回值,提高程序健壮性   
    
                    用const用修饰函数参数是一种常见的行为,见下面代码:   
    
                              const   bigint   operator+(const   bigint&   bigvar1,   const   bigint&   bigvar2)   
    
                              {         return     bigvar1.value+bigvar2.value;   }   
    
  由于bigvar1和bigvar2   都是类类型,为了提高传值的效率,所以就用对象的引用,但是这样就有一个问题,我们不能阻止在函数内部修改bigvar1和bigvar2的值,解决办法只能用const,这就是我们在非内部数据类型的函数参数传递中常用的一种”const引用传递”,它可得到高效率,同时阻止函数内部对对象进行修改。   
    
  再看看对象前面的const(bigint前面)       它的作用是不允许下面的代码存在:   (a+b)   =   c     //a,b,c都是bigint类型   
    
  上面的代码很显然是没有意义,它对一个运算结果进行赋值,我们就应该加上const来阻止这样的代码发生。       
    
  对于类的成员函数,若不会修改数据成员,我们都应该有const来声明,若我编写这样的函数时不小心修改了类的数据成员或调用非const的成员函数,编译器就会给予相关的提示。看看下面的代码:   
    
            class   myprint   
    
  {   
    
    public:   
    
                  myprint():printcount(0){};   
    
                  void   print();   
    
                  int   getcount()   const;   
    
    private:   
    
                    myprint(const   myprint&);   
    
                  myprint&   operator=(const   myprint&);   
    
                  int   printcount;   
    
  };   

在const成员函数中就会调用const版本的下标重载,非const版本一般用于修改值,比如cin>>x[i];

  void   myprint::print(){}   
    
  int   myprint::getcount()   const   
    
  {   
    
        ++printcount;       //错误,const成员函数不能修改类的数据成员   
    
        print();                         //错误,const成员函数不能调用非const成员函数   
    
        return   printcount;   
    
  }   
    
  用const来修饰成员函数实际上修饰的是this指针,所以静态成员函数不能声明为const,原因很简单:静态成员函数没有this指针。这里要注意const成员函数中关键字const是放在成员函数的最后面。   
    
  有时候我的确要在const成员函数中修改类的内部数据员,这时应该怎么办呢,幸运的是标准c++提供的关键字mutable来达到,只要在类数据成员前加上关键字mutable:   
    
  class   myprint   
  {   
    
  public:   
    
  ……   
    
                              int   getcount()   const;   
    
                    private:   
    
                              ……   
    
                              mutable   int   printcount;   
    
  };   
    
  ……   
    
            int   myprint::getcount()   const   
    
  {   
    
                    ++printcount;//正确,因为printcount有关键字mutable修饰   
    
                              ……   
    
        return   printcount;   
    
  }   
    
  当然,还有其它方法(使用const_cast或通过指针间接来修改或通过成员函数的this指针)同样能达到修改的目的,但最好是用mutable。   
    
  5.       用const来修饰重载的类的成员函数。   
    
                    有时候我们要为类提供成员函数的const重载版本,以适应不同情况的需要,例如

  

class Vector

{

     private:

          int   rep[size];

    public:

          const   int &   operator[](int   index)   const      // const 版本的下标重载

     {

           return   rep[index];

      }

 

     int &    operator[] (int   index)      // 非const版本的下标重载

    {

          return    rep[index];

    }

}

     

 


  其实   const的作用应该不止上面说的那些,但可以说一些常用的功能都提到了。在合适使用cosnt的地方,应该尽量使,使程序变得简单,清晰.   
    
            最后,可以看看这个函数中所有const的意义:   
    
                    const   char*   const   foo(char   const   *   const   str)   const   
    
  第一个const表示返回类型为const,也就是不能把此函数的返回值当作左值来使用。   
    
  第二个const表示指针的不可变性,但在这是可以省略,因为返类型已经是const。   
    
  第三个cosnt表示str的常量性,也就其内容是不能改变,可以写在其前面的char的前面。   
    
  第四个cosnt表示str的指针的常量性,也就是此指针不能指向别的地址。   
    
  第五个cosnt表示此函数的常量性(前提是类的成员函数),不能修改所在类的数据成员。  

C++中const作用

标签:

原文地址:http://www.cnblogs.com/benniuniu-gj/p/4451569.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!