[Cpp基础] [05] const与constexpr

Last Updated on 2021年1月24日

const限定符

  • const是一种编译期特性,用于限定对象的编译期写入权限
    • 换言之,其实可以通过各种trick在运行期写入对象.
    • 当项目很大,或者开发人员很多时,使用const就能利用编译器约束开发人员的行为,给开发人员做一定提醒.
    • const值往往还可以供编译器进行优化.
  • 原则上,当我们创建一个变量时,若认为它不应当被修改,就应当声明称const型.最常用的场合是函数形参/返回值中的const T &.
  • const限定的全局对象默认是static的,不会跨文件共享
  • const在与指针联用时,要注意限定的部分.规定:若限定指针自身为不可写,则将const写在*右侧;若是指向的对象不可写,则const写在*左侧.
  • const用于限定对象自身不可写,那么该对象必须初始化.
  • 对于自定义类,也可以限定this指向const T

constexpr限定符(C++11)

  • constexpr是一种编译期特性.它用于限定表达式必须可以在编译期求值.
  • constexpr可以用于创建变量,创建的变量都是const型,且初始化部分必须可以编译期求值.
  • 特例:指针可以用静态区地址初始化.
    • 例如,constexpr int * p=&a;,只要a是静态区的对象,那么这个语法就是正确的.
    • 这种constexpr没有值的意义,仅能作为类似于”宏”的工具存在.
    • 显然,右侧symbol对应的地址只能在链接期或运行期确定,必然是没有值的意义.
    • 编译器只能确定指针的对应的symbol是唯一且已知的,从而进行”宏”形式的替换.例如,已知constexpr int * p=&a;时,p[0]对编译器而言,完全等价于*(&a+1)
    • 这种constexpr指针一般是和当前编译单元的static symbol配合使用constexpr auto p = symbol.因为编译器此时不但能知道 p与symbol的对应关系,还可能根据symbol的内容进一步进行优化.
  • constexpr可以用于限定函数,功能是:若该函数的输入为字面值常量,那么该函数必须可以在编译期求值.
    • constexpr函数在形式上也有较为严格的限制
    • 构造函数也可以是constexpr的,只要它足够简单.
    • constexpr函数默认是inline的.
  • 当一个类满足一些(很苛刻的)条件时,类对象也可以作为字面值常量.
  • 使用constexpr不但有利于编译器优化(编译期替换),还可以切实的产生运行期的对象,从而保证运行期可以作为const对象传入,这是define所不能做到的.