简单分类:
         常变量        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. C语言占位符(待完善)

    %c 读入一个字符 %s 读入一个字符串,遇到空格制表符或者换行符时结束. %d 读入一个十进制整数 %x或者%X   读入一个十六进制整数(读出时,%x:小写,%X:大写) %o   读入一个八进制 ...

  2. 从源码看commit和commitAllowingStateLoss方法区别

    Fragment介绍 在很久以前,也就是我刚开始写Android时(大约在2012年的冬天--),那时候如果要实现像下面微信一样的Tab切换页面,需要继承TabActivity,然后使用TabHost ...

  3. [LC] 328. Odd Even Linked List

    Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her ...

  4. Django的乐观锁与悲观锁实现

    1)     事务概念 一组mysql语句,要么执行,要么全不不执行.  2)  mysql事务隔离级别 Read Committed(读取提交内容) 如果是Django2.0以下的版本,需要去修改到 ...

  5. 喜欢B站的用户为何认同感超强?

    前几天视频弹幕网站哔哩哔哩(以下简称"B站"),正式登陆纳斯达克,股票代码"BILI".当日其CEOC兼董事长陈睿在B站的账号上传了上市视频. 打开视频,满眼& ...

  6. IOUtils和FileUtils的学习笔记

    pom文件导入依赖import org.apache.commons.io.FileUtils; <dependency> <groupId>commons-io</gr ...

  7. [洛谷P3384] [模板] 树链剖分

    题目传送门 显然是一道模板题. 然而索引出现了错误,狂wa不止. 感谢神犇Dr_J指正.%%%orz. 建线段树的时候,第44行. 把sum[p]=bv[pos[l]]%mod;打成了sum[p]=b ...

  8. URL与URI与URN的区别与联系

    1.什么是URL? 统一资源定位符(或称统一资源定位器/定位地址.URL地址等[1],英语:Uniform Resource Locator,常缩写为URL),有时也被俗称为网页地址(网址).如同在网 ...

  9. 初等数论-Base-2(扩展欧几里得算法,同余,线性同余方程,(附:裴蜀定理的证明))

    我们接着上面的欧几里得算法说 扩展欧几里得算法 扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式\(^①\): ax+by = gcd(a, b) =d(解一定存在,根据数论中的 ...

  10. python 简单主机批量管理工具

    需求: 主机分组 主机信息配置文件用configparser解析 可批量执行命令.发送文件,结果实时返回,执行格式如下  batch_run  -h h1,h2,h3   -g web_cluster ...