C++中const的使用

const char*, char const*, char*const的区别问题几乎是C++面试中每次都会有的题目。

 

事实上这个概念谁都有只是三种声明方式非常相似很容易记混。

Bjarne在他的The C++ Programming Language里面给出过一个助记的方法:

把一个声明从右向左读。

 

char * const cp; ( * 读成 pointer to )

cp is a const pointer to char

 

const char * p;

p is a pointer to const char;

 

char const * p;

同上因为C++里面没有const*的运算符,所以const只能属于前面的类型。

C++const的使用

经常看到一些公司的笔试题中考到const,如果能在程序题中使用const,那么程序题的得分必然会高一个等级,偶现在来总结一下。
参考书目王咏刚 王咏武<<道法自然-面向对象实践指南>>

1.使用const的好处 
   1.1
<<C++编程规范>>中的说法是尽量使用const来代替#define”.如果你使用下面的语句定义一个宏(宏:文字替换而已
)
         const int MAX_LENGTH = 100;   
   
编译器就可以看到MAX_LENGTH这个符号,并且可以对MAX_LENGTH进行类型检查,在代码发生错误时也能正确地报出错误位置。

   1.2
在团队开发中有用,比如你写一个函数计算字符串的长度,原型写成int MyStrLen(const char * str),则表示这个函数并不会改变str所指向的内容(*str).这样使用起来更加安全,const限制能保证团队的开发人员按正确的方式使用已有代码。

2.使用const来标识常量
这个是笔试喜欢考的东东,考改错的可能性比较大,或者问答题(偶上次TrendMicro考的是改错题,偶做得还不错)

   //
整型常量,以后不能再对它赋值,因此必需赋一个初值

   int const number = 1;

   //
同上,可见const放在int前面或后面的意义是一样的
   const int number = 1;

   //
指向常量的变量指针,*p不可变,p可变(可指向别处
)
   int const *p;

 
   //
同上,可见const 放在int 前面或后面的意义是一样的

   const int *p;  

   //
指向变量的常量指针,p不可变,但p指向的内容number1可变,p以后不能改变,所以必须赋初值     
   int* const p = &number1;     
   
   //
指向常量的常量指针,p不可变,number也不可变,p以后不能改变,所以必须赋初值

   const int * const p = &number;

   //
引用,C++引用都是常量引用,引用的指向不可变,一个引用指向一个变量后就不能再改变它使它指向另一个变量(因此必
   //
须赋初值),当然引用所指向的内容可以改变(人家指向的是变量嘛),引用一般是出现在函数的参数中
   int & number2 = number;

这个其实很容易记的,主要是看const修饰的是谁

3.修饰类的常量成员
  
如果一个常量只会在一个类里使用,那么我们就不应该把它定义为全局常量,我们应该把我定义在类的内部
      {
       const int MAX_LENGTH = 100;
  class Example

    public:
,要移到外面去

   const int Example::MAX_LENGTH = 100;//static 
的常量不能在类中定义
      
  4.
修饰函数的参数

  
大家都知道C++中函数的参数是按值传递的,当我们要传入一个大型对象的时候,使用按值传递就很不实惠,因为按值传递会生成该对象的一个COPY.浪费呀!!因此在传递对象的时候最好使用指针或引用.
   
但是在一般情况下,我们并不希望函数改变我们所传入的参数,而使用指针或引用做参数就存在被修改的可能性.
   
因此对于不应当被修改的东东我们应当使用const来修饰之


  
比如写一个字符串COPY的函数
   bool CopyString(MyString& szDest,const MyString& szSrc);//
假设MyString是我自己定义的一个字符串类
  
上面的函数表明,源字符串szSrc不会(也不应当)CopyString函数修改,而目标字符串szDest当然要改变了.

5.修饰类的成员函数
   
先写一个不用const修饰成员函数的类
   class MyString//
我的字符串类(仅仅用于教学,没有什么实际的意义)
   {
   //......
   private:
           int GetLength();//
获得串的长度     void SetLength(int len);//设置长度
      //......
   };
   ///GetLength
的实现

   int MyString::GetLength()
   {
      return this->len;
   }
   ///SetLength
的实现
   void MyString::SetLength(int len)
   {
      this->len = len;
   }

   
类的成员函数(内联除外)是另外安排空间的,并不放在类的里面,类的各个对象调用的都是外部的同一个函数.如:
   MyString s2;
   s2.SetLength(2);

   s1s2调用的是同一份函数体,那SetLength(...)如何区分来自于不同的对象的调用呢?参考<<深度探索C++对象模型>>可知道
  
其实GetLength函数的原型并不是GetLength( )而是GetLength(MyString * const this),s1调用GetLength时其实是调用GetLength(s1),这里用const来修饰this说明this是一个不可变的指针,你不能在GetLength函数里把它指向别处,当然你可以改变this所指向的内容.
   
使用const修饰类的成员函数(就是在括号后加上一个const,形如:int GetLength()const;),编译器会为我们生成以下函数

   GetLength(MyString const  * const this)
  
由该原型可以看出,const修饰成员函数的作用在于:表明该成员函数不会修改*this内容,比如GetLength的职责只是返回字符串的长度,而不是修改对象中的任何数据.

  
下面说说作用(也就是笔试考点PS:前几天趋势公司考过,怕大家以后笔试遇到,于是就帖出来了

   bool CopyString(MyString & szDest,const MyString & szStr)
   {
       //......
       szDest.SetLength(szStr.GetLength());//
假设我们就只做这件无聊的事

       //......
   }

   
如果GetLength不是const型,则不能编译通过,解释如下
   CopyString
的第二个参数 const MyString & szStr表明szStr是一个const引用,当szStr.GetLength()时传递给GetLength的第一个参数是szStr的类型是MyString const *const szStr,
而未经const修饰的GetLength接受的第一个参数是MyString * const this,两者不匹配编译出错

   
   
如果用const修饰GetLengthGetLength的第一个参数是MyString const  * const this szStr匹配,编译通过

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值