• const修饰符总结


      在 C/C++ 语言中,const关键字是一种修饰符。所谓“修饰符”,就是在编译器进行编译的过程中,给编译器一些“要求”或“提示”,但修饰符本身,并不产生任何实际代码。就 const 修饰符而言,它用来告诉编译器,被修饰的这些东西,具有“只读”的特点。在编译的过程中,一旦我们的代码试图去改变这些东西,编译器就应该给出错误提示。

      所以,const修饰符的作用主要是利用编译器帮助我们检查自己代码的正确性

      虽然const对于最终代码没有影响,但是尽可能使用const,将帮助我们避免很多错误,提高程序正确率

      

      在C/C++中,常见 const 用法有以下几种

    一、const 变量

      const 变量指的是,此变量的值是只读的,不应该被改变。

    • 如果我们在程序中试图修改 const 变量的值,在编译的时候,编译器将给出错误提示。
    • 正因为 const 变量的值在给定以后不能改变,所以 const 变量必须被初始化(如果不初始化,之后还怎么赋值呢?)如果我们不初始化 const 变量,编译时也会有错误提示。

    二、const 类对象

      const类对象指的是,此类对象不应该被改变。

    • const 类对象与 const 变量并无实质不同,只在于类对象的 “改变” 定义。
    • 类对象的 “改变” 定义:改变任何成员变量的值,调用任何非const成员函数

    三、指向 const 变量的指针

      指向 const 变量的指针,指的是一个指针,其中保存着一个 const 变量的地址。

    • 由于指针指向一个 const 变量,所以通过指针,不能修改这个 const 变量的值。
    • 虽然指针指向的值不能改变,但是指针的指向可以改变

    四、const 指针

      const指针指的是,一个指针本身经过 const 修饰,自身内容(指针指向)不应该发生改变。

    • 指针的指向一经确定,不能改变。指针指向的内容,可以改变。

    指针也是一种变量,只不过其内容保存的是地址而已。所以const指针的内容不能改变,也即是它的指向不能改变。

      const指针和指向const变量的指针,在写法上容易使人混淆。给大家介绍一种我自己用着比较顺手的区分方法:从右向左,依次结合,const就近结合。

      比如,int * const p 可以这样进行解读:

      1、int * ( const p ):变量p 经过 const 修饰,为只读变量。

      2、int (* (const p)):(const p 现在作为一个整体) 只读变量p是一个指针。

      3、(int (* (const p))):(同样的 * const p 作为一个整体) 这个只读的指针p,指向一个int型变量。

      于是,可以区分出 int * const p 是一个指向 int 型的const指针。

      再比如,const int * p 可以这样解读:

      1、const int (* p):变量p是一个指针。

      2、(const int) (* p):(const与就近的 int 结合)这个指针指向 const int 型变量。

      所以,const int * p 是一个指向 const 整形变量的指针。

    六、const 变量作为函数参数

      在函数调用的过程中,函数的参数是建立在函数的栈上的变量。既然是变量,就可以通过 const 进行修饰。

    • 将函数参数声明为 const 类型,表示对于函数来说,这个参数是一个 const 变量。也就是说,函数内部不能够改变这个参数的值。
    • 将函数参数是一个指针,把它声明为 “指向 const 变量的指针” ,允许上层使用 ”指向 const 变量的指针“ 或 普通指针 作为参数,调用函数。(如果参数声明的是普通指针,则不允许使用 指向 const 变量的指针 作为参数调用)(与编译器有关)

      为什么 int * 可以隐式转换为 const int *,但是反向就不可以呢?相信各位读者已经想到了。隐式转换不放宽对于变量的要求,而 const 型的变量显然比非 const 型变量要求严格,所以不能由 const int * 转为 int *。

    七、const 返回值

      const 型的返回值,指的是函数的返回值为一个 const 变量。

    • 函数返回const返回值,主要用于函数返回const引用。

    八、const 成员变量

      const 成员变量指的是类中的成员变量为只读,不能够被修改(包括在类外部和类内部)。

    • const 成员变量必须被初始化(在相关构造函数的初始化列表中),初始化后,不能够被修改
    • 静态 const 成员变量需要在类外部单独定义并初始化(可定义在头文件)

      类对象的实例化过程可以理解为包含以下步骤:首先,开辟整个类对象的内存空间。之后,根据类成员情况,分配各个成员变量的内存空间,并通过构造函数的初始化列表进行初始化。最后,执行构造函数中的代码。由于 const 成员变量必须在定义(分配内存空间)时,就进行初始化。所以需要在够在函数的初始化列表中初始化。const成员在初始化之后,其值就不允许改变了,即便在构造内部也是不允许的。

      静态成员变量并不属于某个类对象,而是整个类共有的。静态成员变量可以不依附于某个实例化后的类对象进行访问。那么,静态成员变量的值,应该在任何实例化操作之前,就能够进行改变(否则,只有实例化至少一个对象,才能访问静态成员)。所以,静态成员变量不能够由构造函数进行内存分配,而应该在类外部单独定义,在实例化任何对象之前,就开辟好空间。又由于 const 成员变量 必须初始化,所以静态成员变量必须在定义的时候就初始化。

    九、const 成员函数

      const成员函数指的是,此函数不应该修改任何成员变量。

    • 传给const成员函数的this指针,是指向 const 对象 的 const 指针
    • const成员函数,不能够修改任何成员变量,除非成员变量被 mutable 修饰符修饰

      在成员函数调用的过程中,都有一个 this 指针被当做参数隐性地传递给成员函数(可能通过栈,也可能通过CPU寄存器)。这个this指针,指向调用这个函数的对象(这样,成员函数才能找到成员变量的地址,从而对其进行操作)。这个this指针,是个 const指针,不能修改其指向(你不希望这个对象的函数,修改了那个对象的成员变量,对吧?)。

      传递给const成员函数的this指针,指向一个const对象。也就是说,在const成员函数内部,这个this指针是一个指向const对象的const指针。通过第二节的探讨,相信大家已经能够明白,为什么const成员函数不能修改任何成员变量了。

      mutable 修饰符使得const函数的行为有了一些灵活性。相当于提醒编译器,这个成员变量比较特殊,就不要进行任何只读检查了。

      我们在第二节留下了一个问题 “为什么 const 对象只能够调用const成员函数呢?”,其实是这样的。由于对象本身通过 const 修饰,那么指向这个对象的指针也就是指向const对象的const指针了。换句话说,指向这个对象的this指针就是指向const对象的const指针。一般成员函数要求的this指针(别忘了this指针也是一个参数)为:指向对象的const指针。所以此处发生了参数不匹配,无法进行调用。而 const 成员函数要求的this指针,恰恰是 指向const对象的const指针。所以依然能够调用。

      

  • 相关阅读:
    Spring Boot 缓存技术:Spring Boot
    Java基础之Iterable接口
    使用sqlyog连接 Mysql 出现1251错误
    IDEA更改主题插件——Material Theme UI详解
    免安装版的Mysql
    使用Nexus搭建Maven私服
    Spring之注解注入bean
    Idea springboot 配置热部署
    Spring Boot 异常处理与单元测试
    Ubuntu20.04在线安装VMware-Tools
  • 原文地址:https://www.cnblogs.com/blogXiong/p/3335733.html
Copyright © 2020-2023  润新知