简单分类:
         常变量        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!";

    • 内部链接性还意味着,每个文件都有自己的一组常量,而不是所有文件 共享一组常量。每个定义都是所属文件私有的,这就是能够将常量定义放在头文件中的原因。这样,只要在两个源代码文件中包括同一个头文件,则它们将获得同一组常量。

   










const 详解的更多相关文章

  1. const详解

    详解C++中的const关键字

  2. C++中的指针(*)、引用(&)、const详解(一、定义变量)

    一.前言 本人作为一个工作了5年的程序员,程序生涯最初是从c/c++开始的,但是始终不能很熟悉的理解c语言中的指针和c++中的引用,归其原因,一部分自己没有静下心来思考,一部分原因是其自身的复杂性. ...

  3. C++中的const详解

    const的用法,特别是用在函数后面 在普通的非 const成员函数中,this的类型是一个指向类类型的 const指针.可以改变this所指向的值,但不能改变 this所保存的地址. 在 const ...

  4. C++ 中的 const 详解

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4235721.html 1.为什么使用 const int 而不使用 #define 在使用# ...

  5. C++ 常量类型 const 详解

    1.什么是const? 常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的.(当然,我们可以偷梁换柱进行更新:) 2.为什么引入const? const 推出的初始目的 ...

  6. let与const详解

    在ES6中,js首次引入了块级作用域的概念,而什么是块级作用域? 众所就知,在js当中存在预解析的概念,就是变量提升.并且只存在全局作用域和私有作用域.在全局定义的变量就是全局变量,而在函数内部定义的 ...

  7. [js高手之路] es6系列教程 - var, let, const详解

    function show( flag ){ console.log( a ); if( flag ){ var a = 'ghostwu'; return a; } else { console.l ...

  8. ES6 let和const详解及使用细节

    ES6之前javascript只有全局作用域和函数作用域,所以经常会遇到变量提升了或者使用闭包的时候出错的问题. 所有a[i]都会输出10: var arr=[]; for (var i=0;i< ...

  9. ES6中let和const详解

    let和var一样也是用来定义变量,不同之处在于let是块级作用域,只在所定义的块级作用域中生效,一个花括号便是一个块级作用域 {var a="我是var定义的";let b=&q ...

  10. 函数新特性、内联函数、const详解

    一.函数回顾与后置返回类型 函数定义中,形参如果在函数体内用不到的话,则可以不给形参变量名字,只给其类型. 函数声明时,可以只有形参类型,没有形参名 把函数返回类型放到函数名字之前,这种写法,叫前置返 ...

随机推荐

  1. 通过HTTP向kafka发送数据

    在大数据整个处理流程过程中,数据的流向是一个很重要的问题,本篇博客主要记录数据是怎么从http发送到kafka的. 使用技术点: 1. java的Vert.x框架 (关于java框架Vert.x的使用 ...

  2. deeplearning.ai 神经网络和深度学习 week2 神经网络基础

    1. Logistic回归是用于二分分类的算法. 对于m个样本的训练集,我们可能会习惯于使用for循环一个个处理,但在机器学习中,是把每一个样本写成一个列向量x,然后把m个列向量拼成一个矩阵X.这个矩 ...

  3. java中的锁——列队同步器

    队列同步器 队列同步器(AbstractQueuedSynchronizer)为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量.事件,等等)提供一个框架.此类的设计目标是成为依 ...

  4. JavaWeb防注入知识点(一)

    一.防sql注入办法 在apache commons-lang(2.3以上版本)中为我们提供了一个方便做转义的工具类,主要是为了防止sql注入,xss注入攻击的功能.总共提供了以下几个方法: 1.es ...

  5. C# 开启线程的几种方式

    1.异步委托开启线程 public static void Main(string[] args) { Action<int,int> a=add; a.BeginInvoke(,,nul ...

  6. SHELL用法八(Grep语句)

    1.SHELL编程Grep语句案例实战 1)Find是Linux操作系统文件和目录的路径检索.查询工具,而Grep是Linux系统下文本文件内容检索或者匹配工具,Grep称为全局正则表达式检索工具,在 ...

  7. js - 常用的继承

    零.序言 参考资料:JavaScript常用八种继承方案: 注:1.此篇笔记是站在上述资料的肩膀上的一篇小结: 2.阅读之前建议温习一下 js 中的 prototype 和 constructor:( ...

  8. 【React.js小书】动手实现 React-redux(五):Provider - 方志

    我们要把 context 相关的代码从所有业务组件中清除出去,现在的代码里面还有一个地方是被污染的.那就是 src/index.js 里面的 Index: 1234567891011121314151 ...

  9. Data Visualization and D3.js 笔记(1)

    课程地址: https://classroom.udacity.com/courses/ud507 什么是数据可视化? 高效传达一个故事/概念,探索数据的pattern 通过颜色.尺寸.形式在视觉上表 ...

  10. LVS+Keepalived 配置

    LVS+Keepalived配置 环境准备 LVS1:192.168.1.1 LVS2:192.168.1.2 MySQL Server1:192.168.1.13 MySQL Server2:192 ...