zoukankan      html  css  js  c++  java
  • const 详解


    简单分类:
             常变量        const 类型 变量名  或者   类型 const  变量名
             常引用        const 类型& 引用名  或者  类型 const & 引用名
             常对象        const 类名     对象名  或者  类名 const     对象名
             常数组        const 类型     数组名   或者  类型  const     数组名
             常成员函数    类名::fun(形参) const
             常指针        const 类型*指针名
                                类型 const *指针名
                                类型* const 指针名

    说明:
      1. 常引用的写法只能是:
          1. const 类型 & 引用名
          2. 类型 const & 引用名
      2. 常成员函数const为什么要写在后面?《高质量C++/C编程指南》戏言,没位置只好写在后面。

    1. 常量
      • 常量因为不允许赋值,所以必须在声明时进行初始化。
        • const int model = 90; //ok;
        • const int x;//error
        • 在类中的数据成员(常量),不能在声明中对其初始化,也不能在构造函数中对其初始化,唯一的方法就是在类的构造函数初始化列表中对常量数据成员初始化。
      • 对于如下情形:
        • const int c1=1;    c1在编译时就会对其求值。有点像会把程序中所有的遇到c1的地方替换成1,而且也不为c1分配空间。若有const int *p = &c1;此时就必须为c1分配空间了。
        • const int c2 =m_f(3);编译器不能直接确定c2的值,需为c2分配空间。
        • 编译器为const限制了使用方式,我们可以绕过编译器的限制而对const常量进行修改。
        • const int  i = 10;
          int *pi = (int *)&i;
          *pi = 30;
          cout<<i<<endl;
        • 此时输出结果为10
        • int f(){return 10}
          const int i = f();
          int *pi = (int*)&i;
          *pi = 30;
          cout<<i<<endl;
        • 此时输出结果为30。
        • 差异在于第一段代码虽为其分配空间,但类似替换的效果使其输出为10.第二段代码绕过编译器,对常量进行了修改。
      • const最常见的用途是作为数组的界和作为switch的分情况标号。
      • const对象默认为文件的局部变量(同第5点的链接性)(static与extern水火不熔)
        • 变量
        • //file_1.cc
          int counter;
          //file_2.cc
          extern int counter;
          counter++;
        • 常量
        • //file_1.cc
          //defines and initializes a const that is accessible to other files
          extern const int i =f();
          //file_2.cc
          //uses i from file_1.cc
          extern const int i;
    2. 指针和常量
      • char s[] = "Gorm";
        const char* pc = s;        //a pointer to const char
        pc[3] = 'g';               //error
        pc = p;                    //ok
        char * const cp = s ;      //a cosnt pointer to char
        cp[3] = 'a'              //ok
        cp = p;                    //error
        const char * const cpc =s ;//a const pointer to const char
        cpc[3] = 'a';              //error
        cpc = p;                   //error
      • 秘诀:从右向左看,看const和*的位置关系。
      • 注:可以将一个变量地址赋给一个常量的指针,因为这样做不会造成任何损害。不能将常量的地址赋给一个未加限制的指针,因为这样将会允许修改该对象的值(这里说的不能是不要这么做,而不是编译器不允许这么做,这应该是编译器的一个bug了,忘记前面我们说的绕过编译器改常量值了吗?
    3. 函数参数
      • 对于非内部类型的参数,像void Func(A a)因拷贝效率低,应改写成void Func(const A& a )
      • 对于内部类型的参数void Func(const int &x)由于拷贝跟引用代价相似
    4. const 成员函数(任何不修改数据成员的函数都应该声明为const类型)
      • clss Stack
        {
        public:
            void Push(int elem);
            int Pop(void);
            int GetCount(void) const;
            private:
            int m_num;
            int m_data[100];
        };
        int Stack::GetCount(void) const
        {
            ++m_num;//error,本函数为const
            pop();//error,调用非const函数
            return m_num;
        }
    5. const链接性
      • 在默认情况下全局变量的链接性为外部的,但const全局变量的链接性为内部的。也就是说,在C++看来,全局const定义就像使用了static说明符一样,作用域只在本文件。
    const int fingers = 10; //same as static const int fingers = 10;
    int main(void)
    {
    ...
      • 假设将一组常量放在头文件中,并在同一个程序的多个文件中使用该头文件。那么,预处理器将头文件的内容包含到每个源文件后,所有的源文件都将包含类似下面这样的定义:
      • const int fingers =10;
        const char * warning = "Wak!";
      • 内部链接性还意味着,每个文件都有自己的一组常量,而不是所有文件 共享一组常量。每个定义都是所属文件私有的,这就是能够将常量定义放在头文件中的原因。这样,只要在两个源代码文件中包括同一个头文件,则它们将获得同一组常量。

       














  • 相关阅读:
    Objective-C中的Block回调模式
    [LINUX-02]linux内存管理
    Linux设备模型(8)_platform设备
    Face Alignment
    dlib 人脸识别论文 One Millisecond Face Alignment with an Ensemble of Regression Trees
    linux内核函数kmap_atomic用法
    [LINUX-01]对比LINUX和CORTEX-M启动流程
    -02-建立PetaLinux工程
    linux内核启动流程(文章最后流程图)
    uboot笔记:uboot命令分析+实现
  • 原文地址:https://www.cnblogs.com/codetravel/p/4534481.html
Copyright © 2011-2022 走看看