const使用详解

一、常变量  
  变量用const修饰,其值不得被改变。任何改变此变量的代码都会产生编译错误。Const加在数据类型前后均可。  
  例如:

  1. void   main(void)   
  2. {   
  3.           const   int   i   =   10;         //i,j都用作常变量   
  4.           int   const   j   =   20;   
  5.           i   =   15;                         //错误,常变量不能改变   
  6.           j   =   25;                         //错误,常变量不能改变   
  7. }   

二、常指针   
       const跟指针一起使用的时候有两种方法。    
    const可用来限制指针不可变。也就是说指针指向的内存地址不可变,但可以随意改变该地址指向的内存的内容。     

  1.   void   main(void)   
  2.   {   
  3.           char*   const   str   =   "Hello,   World";         //常指针,指向字符串   
  4.           *str   =   ''M'';                         //可以改变字符串内容   
  5.           str   =   "Bye,   World";                 //错误,如能改变常指针指向的内存地址   
  6.   }   

    
  const也可用来限制指针指向的内存不可变,但指针指向的内存地址可变。

  1. void   main(void)   
  2.   {   
  3.           const   char*   str   =   "Hello,   World";         //指针,指向字符串常量   
  4.           *str   =   ''M'';                 //错误,不能改变字符串内容   
  5.           str   =   "Bye,   World";         //修改指针使其指向另一个字符串   
  6.           *str   =   ''M'';                 //错误,仍不能改变字符串内容   
  7.   }   

    
   看完上面的两个例子,是不是糊涂了?告诉你一个诀窍,在第一个例子中,const用来修饰指针str,str不可变(也就是指向字符的常指针);第二个例子中,const用来修饰char*,字符串char*不可变(也就是指向字符串常量的指针)。    
       这两种方式可以组合起来使用,使指针和内存内容都不可变。   

  1.   void   main(void)   
  2.   {   
  3.           const   char*   const   str   =   "Hello,   World";                 //指向字符串常量的常指针   
  4.           *str   =   ''M'';                         //错误,不能改变字符串内容   
  5.           str   =   "Bye,   World";                 //错误,不能改变指针指向的地址   
  6.   }   

    
  三、const和引用  
      引用实际上就是变量的别名,这里有几条规则:   
      1、声明变量时必须初始化  
      2、一经初始化,引用不能在指向其它变量。  
      3、任何对引用的改变都将改变原变量。    
      4、引用和变量本身指向同一内存地址。    
     下面的例子演示了以上的规则:   

  1. void   main(void)   
  2.   {   
  3.           int   i   =   10;                                         //i和j是int型变量   
  4.           int   j   =   20;                   
  5.           int   &r   =   i;                                         //r   是变量i的引用   
  6.           int   &s;                                                 //错误,声明引用时必须初始化   
  7.           i   =   15;                                                 //i   和   r   都等于15   
  8.           i++;                                                 //i   和   r都等于16   
  9.           r   =   18;                                                 //i   和r   都等于18   
  10.           printf("Address   of   i=%u,   Address   of   r=%u",&i,&r);         //内存地址相同   
  11.           r   =   j;                                                 //i   和   r都等于20,但r不是j的引用   
  12.           r++;                                                 //i   和   r   都等于21,   j   仍等于20   
  13.   }   


  用const修饰引用,使应用不可修改,但这并不耽误引用反映任何对变量的修改。Const加在数据类型前后均可。  
  例如:

  1. void   main(void)   
  2.   {   
  3.           int   i   =   10;   
  4.           int   j   =   100;   
  5.           const   int   &r   =   i;   
  6.           int   const   &s   =   j;   
  7.           r   =   20;                     //错,不能改变内容   
  8.           s   =   50;                     //错,不能改变内容   
  9.           i   =   15;                     //   i和r   都等于15   
  10.           j   =   25;                     //   j和s   都等于25   
  11.   }   

    
  四、const和成员函数  
     声明成员函数时,末尾加const修饰,表示在成员函数内不得改变该对象的任何数据。这种模式常被用来表示对象数据只读的访问模式。例如:  

  1. class   MyClass   
  2.   {   
  3.           char   *str   ="Hello,   World";   
  4.           MyClass()   
  5.           {   
  6.                   //void   constructor   
  7.           }   
  8.             
  9.           ~MyClass()   
  10.           {   
  11.                   //destructor   
  12.           }   
  13.     
  14.           char   ValueAt(int   pos)   const         //const   method   is   an   accessor   method   
  15.           {   
  16.                   if(pos   >=   12)   
  17.                                 return   0;   
  18.   *str   =   ''M'';             //错误,不得修改该对象   
  19.                   return   str[pos];         //return   the   value   at   position   pos   
  20.           }   
  21.   }   

    
  五、const和重载  
  重载函数的时候也可以使用const,考虑下面的代码:  

  1. class   MyClass   
  2.   {   
  3.           char   *str   ="Hello,   World";   
  4.           MyClass()   
  5.           {   
  6.                   //void   constructor   
  7.           }   
  8.             
  9.           ~MyClass()   
  10.           {   
  11.                   //destructor   
  12.           }   
  13.     
  14.           char   ValueAt(int   pos)   const         //const   method   is   an   accessor   method   
  15.           {   
  16.                   if(pos   >=   12)   
  17.                                 return   0;   
  18.                   return   str[pos];         //return   the   value   at   position   pos   
  19.           }   
  20.             
  21.           char&   ValueAt(int   pos)                 //通过返回引用设置内存内容   
  22.           {   
  23.                   if(pos   >=   12)   
  24.                                 return   NULL;   
  25.                   return   str[pos];   
  26.           }   
  27.   }   
  28.     

    
  在上面的例子中,ValueAt是被重载的。const实际上是函数参数的一部分,在第一个成员函数中它限制这个函数不能改变对象的数据,而第二个则没有。这个例子只是用来说明const可以用来重载函数,没有什么实用意义。

  实际上我们需要一个新版本的GetValue。如果GetValue被用在operator=的右边,它就会充当一个变量;如果GetValue被用作一元操作符,那么返回的引用可以被修改。这种用法常用来重载操作符。String类的operator[]是个很好的例子。    

  1.   class   MyClass   
  2.   {   
  3.           char   *str   ="Hello,   World";   
  4.           MyClass()   
  5.           {   
  6.                   //void   constructor   
  7.           }   
  8.             
  9.           ~MyClass()   
  10.           {   
  11.                   //destructor   
  12.           }   
  13.     
  14.           char&   operator[](int   pos)                 //通过返回引用可用来更改内存内容   
  15.           {   
  16.                   if(pos   >=   12)   
  17.                                 return   NULL;   
  18.                   return   str[pos];   
  19.           }   
  20.   }   
  21.     
  22.   void   main(void)   
  23.   {   
  24.           MyClass   m;   
  25.           char   ch   =   m[0];                 //ch   等于   ''H''   
  26.           m[0]   =   ''M'';                 //m的成员str变成:Mello,   World   
  27.   }   

    
 六、 const的担心  
  C/C++中,数据传递给函数的方式默认的是值传递,也就是说当参数传递给函数时会产生一个该参数的拷贝,这样该函数内任何对该参数的改变都不会扩展到此函数以外。每次调用该函数都会产生一个拷贝,效率不高,尤其是函数调用的次数很高的时候。  
  例如:

  1. class   MyClass   
  2.   {   
  3.   public:   
  4.           int   x;           
  5.           char   ValueAt(int   pos)   const         //const   method   is   an   accessor   method   
  6.           {   
  7.                   if(pos   >=   12)   
  8.                                 return   0;   
  9.                   return   str[pos];         //return   the   value   at   position   pos   
  10.           }   
  11.           MyClass()   
  12.           {   
  13.                   //void   constructor   
  14.           }   
  15.           ~MyClass()   
  16.           {   
  17.                   //destructor   
  18.           }   
  19.           MyFunc(int   y)         //值传递   
  20.           {   
  21.                   y   =   20;   
  22.                   x   =   y;         //x   和   y   都等于   20.   
  23.           }   
  24.   }   
  25.     
  26.   void   main(void)   
  27.   {   
  28.           MyClass   m;   
  29.           int   z   =   10;   
  30.           m.MyFunc(z);   
  31.           printf("z=%d,   MyClass.x=%d",z,m.x);         //z   不变,   x   等于20.   
  32.   }   

  通过上面的例子可以看出,z没有发生变化,因为MyFunc()操作的是z的拷贝。为了提高效率,我们可以在传递参数的时候,不采用值传递的方式,而采用引用传递。这样传递给函数的是该参数的引用,而不再是该参数的拷贝。然而问题是如果在函数内部改变了参数,这种改变会扩展到函数的外部,有可能会导致错误。在参数前加const修饰保证该参数在函数内部不会被改变。  

 

  1. class   MyClass   
  2.   {   
  3.   public:   
  4.           int   x;   
  5.           MyClass()   
  6.           {   
  7.                   //void   constructor   
  8.           }   
  9.           ~MyClass()   
  10.           {   
  11.                   //destructor   
  12.           }   
  13.           int   MyFunc(const   int&   y)         //引用传递,   没有任何拷贝   
  14.           {   
  15.                   y   =20;         //错误,不能修改常变量   
  16.                   x   =   y           
  17.           }   
  18.   }   
  19.     
  20.   void   main(void)   
  21.   {   
  22.           MyClass   m;   
  23.           int   z   =   10;   
  24.           m.MyFunc(z);   
  25.           printf("z=%d,   MyClass.x=%d",z,m.x);         //z不变,   x等于10.   
  26.   }   

   如此,const通过这种简单安全机制使你写不出那种说不定是什么时候就会掉过头来咬你一口的代码。你应该尽可能的使用const

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值