详解C/C++中const关键字的用法及其与宏常量的比较分享

如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。

  const int * fun2() //调用时 const int *pValue = fun2();          //我们可以把fun2()看作成一个变量,即指针内容不可变。    c.int* const fun3() //调用时 int * const pValue = fun2();          //我们可以把fun2()看作成一个变量,即指针本身不可变。   const int fun1() //这个其实无意义,因为参数返回本身就是赋值。

6.修饰类相关

(1)用const修饰的类成员变量,只能在类的构造函数初始化列表中赋值,不能在类构造函数体内赋值。

  class A  {  public:   A(int x) : a(x) // 正确   {     //a = x; // 错误   }  private:   const int a;  };

(2)const修饰成员函数

用const修饰的类成员函数,在该函数体内不能改变该类对象的任何成员变量, 也不能调用类中任何非const成员函数。一般写在函数的最后来修饰。

  class A  {  public:   int& getValue() const   {    // a = 10; // 错误    return a;   }  private:   int a;   // 非const成员变量  };

a. const成员函数不被允许修改它所在对象的任何一个数据成员。

b. const成员函数能够访问对象的const成员,而其他成员函数不可以。

(3)const修饰类对象/对象指针/对象引用

用const修饰的类对象表示该对象为常量对象,该对象内的任何成员变量都不能被修改。对于对象指针和对象引用也是一样。

因此不能调用该对象的任何非const成员函数,因为对非const成员函数的调用会有修改成员变量的企图。

  class A  {   public:   void funcA() {}   void funcB() const {}  };  int main  {   const A a;   a.funcB(); // 正确   a.funcA(); // X     const A* b = new A();   b->funcB(); // 正确   b->funcA(); // X  }

(4)在类内重载成员函数

  class A   {   public:    void func() {}    void func() const {} // 重载   };

另外,const数据成员只在某个对象生存期内是常量,而对整个类而言是可变的,因为类可以创建多个对象,不同对象的const数据成员值可以不同。

  class A  {  public:   A(int size)      : _size(size) // 正确   {}  private:   const int _size;  };  A a(10); //对象a的_size值为10  A b(20); //对象b的_size值为20

那么,怎样才能建立在整个类中都恒定的常量呢?用枚举常量。

  class A  {  public:   enum{SIZE1 = 10, SIZE2 = 20};//枚举常量  private:    int arr1[SIZE1];    int arr2[SIZE2];  };

枚举常量不会占用对象的存储空间,它们在编译时被全部求值。但缺点是隐含数据类型是只能整数,最大值有限,且不能表示浮点数。

7.修饰全局变量

全局变量的作用域是整个文件,我们应该尽量避免使用全局变量,以为一旦有一个函数改变了全局变量的值,它也会影响到其他引用这个变量的函数,导致除了bug后很难发现,如果一定要用全局变量,我们应该尽量的使用const修饰符进行修饰,这样方式不必要的以为修改,使用的方法与局部变量是相同的。

8.const常量与宏常量的区别

(1).便于进行类型检查

const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误(边际效应)。

  //例子:   void f(const int i) { .........} //对传入的参数进行类型检查,不匹配进行提示

(2)可以节省空间,避免不必要的内存分配

const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。

  #define PI 3.14159   //常量宏  const doulbe Pi=3.14159; //此时并未将Pi放入ROM中      ......   double i=Pi; //此时为Pi分配内存,以后不再分配!   double I=PI; //编译期间进行宏替换,分配内存   double j=Pi; //没有内存分配   double J=PI; //再进行宏替换,又一次分配内存!

(3)提高了效率 

 宏定义是一个“编译时”概念,在预处理阶段展开,不能对宏定义进行调试,生命周期结束于编译时期。const常量是一个“运行时”概念,在程序运行时使用,类似于一个只读数据。

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/488321.html

(0)
上一篇 2020年11月12日
下一篇 2020年11月12日

精彩推荐