天天看点

const 关键字

文章目录

      • 1. const 的设定
      • 2. const 的引用
      • 3. const 和指针
        • 3.1 常量指针
        • 3.2 指针常量
      • 4. 顶层 const 和 底层 const
      • 5. constexpr 和 常量表达式
      • 6. const 修饰成员函数

1. const 的设定

  • const关键字修饰变量时,限制该变量的值不能够被改变

    。 由于const关键字修饰的变量的值不能够改变,所以

    const对象必须初始化

  • 相较同一类型的非常量变量,

    常量变量只能执行不改变其内容的操作

    ,如算术运算、拷贝初始化等;
  • 默认情况下,const对象被设定为仅在文件内有效

    ;若是需要只在一个文件中定义const,而在多个文件中声明并使用,则在const变量的定义和声明前都添加extern关键字;

2. const 的引用

  • 引用不是对象

    ,所以对于引用和const一起出现的情况,只能是引用常量对象,也即对常量的引用;
  • 把引用绑定到常量对象上,称之为

    对常量的引用(reference to const)

    ,简称

    常量引用

  • 引用的类型必须与多引用对象的类型一致,但有两种例外情况:

    初始化常量引用时允许用任意表达式作为初始值

    ,只要该表达式结果能够转换成引用的类型;

    常量引用可能引用的是同一类型的非常量对象

    ,可以理解为引用“自以为是”的觉得自己指向了常量,自觉不允许改变所指对象的值;

3. const 和指针

3.1 常量指针

  • 类似于常量引用,也可以将指针指向一个常量变量,也就是

    指向常量的指针(pointer to const)

    ,又称

    常量指针

    ,其不能用于改变其所指向对象的值;
  • 若想存放常量对象的地址,只能使用指向常量的指针/常量指针;
  • 和常量引用一个道理,常量指针/指向常量的指针也不强制规定所指对象必须是一个常量;

3.2 指针常量

  • 指针是对象

    ,所以可以把指针本身定义为常量,遵循在1中所提到的,

    指针常量(const pointer)

    必须初始化。定义方式为

    type * const var

  • 指针常量表示不变的是指针本身而不是指向的值,所以并不意味着不能通过指针常量修改所指对象的值;

4. 顶层 const 和 底层 const

  • 指针本身是一个对象,其又可以指向一个对象,所以指针本身是不是常量以及指针所指的对象是不是常量是两个相互独立的问题;
  • 顶层const (top-level const):表示指针本身是个常量

    。其可表示任意的对象是常量,适用于任何数据类型;
  • 底层const (low-level const):表示指针所指对象是个常量

    。其与指针、引用等复合类型的基本类型部分有关,其中

    用于声明引用的const都是底层const

  • 当执行对象的拷贝操作时

    ,顶层const不受什么影响,然而

    拷入和拷出的对象必须具有相同的底层const,或两对象的数据类型能够相互转换

    (非常量可以转换成常量);

5. constexpr 和 常量表达式

  • 常量表达式(const expression)

    指值不会改变并在编译过程中就能得到计算结果的表达式。显然,字面值时常量表达式,一般来说函数做右值,函数返回的具体值直到运行时才知道,不是常量表达式;
  • 为了方便分辨一个初始值到底是不是常量表达式,在C++11版本中引入了新关键字

    constexpr

    。允许将变量声明为constexpr类型以便由编译器验证变量是否是一常量表达式;
  • C++11 新标准允许定义一种特殊的constexpr类型的函数,足够简单到编译时就可以计算出返回值,以便用函数初始化constexpr类型变量;
  • 声明为constexpr的变量一定是一个常量,且必须用常量表达式初始化;
  • constexpr指针的初始值必须为nullptr或0,或是存储于某个固定地址中的对象。在constexpr声明中如果定义了一个指针,constexpr只对指针有效,与指针所指对象无关;
const int *p = nullptr; //p是一个指向整型常量的指针
constexpr int *q = nullptr; //q是一个指向整数的常量指针
           

以上讲解了const关键字的语法、含义和引申出的相关概念,对于const关键字的应用推荐查看:

①关于C++ const 的全面总结

②关于const 作用和用法 C++ const 的全面总结

下表列出了const的应用场景:

const 关键字

6. const 修饰成员函数

就如上表中的No.5的作用所说,const也可修饰成员函数,表示该成员函数具有常量性。具体的作用和应用场景见下图所示:

const 关键字

以 std::basic_string 的 operator[] 运算符的重载(函数签名不同)为例,可以更好的理解到,对于一个(非)常量对象其与相关的(非)常量成员函数之间的使用的关系和逻辑。

有关图片中的COW机制,见:标准C++类string的Copy-On-Write技术 和 COPY-ON-WRITE 原理。

简单来说,在复制一个对象时并不是真的在内存中把原来对象的数据复制一份到另外一个地址,而是在新对象的内存映射表中指向同原对象相同的位置,并且把那块 内存的 Copy-On-Write 位设为 1。在对这个对象执行读操作的时候,内存数据没有变动,直接执行就可以。在写的时候,才真正将原始对象复制一份到新的地址,修改新对象的内存映射表到这个 新的位置,然后往这里写。

简介

通俗的称为写时拷贝的一种机制,也就是说读的时候并不需要拷贝

应用场景

并发线程中对同一块资源同时处理数据错乱问题

一般解决方法

1.对同时访问的这块资源加锁,多个线程轮流访问;

2.对每个来读这块资源的线程直接访问就是了,每个来写这块资源的线程就临时拷贝一份资源给他们处理,也就是copy on write。

继续阅读