[C++] C++之const、constexpr变量、constexpr函数总结

const是一种类型修饰符

定义一个变量,它的值不能被改变。比如用一个变量来表示缓冲区的大小。

const int size = 128;//const的int类型
size = 1;//const对象一旦被创建以后,其值就不能再改变
    
const int i = get_size();//正确,运行时初始化
const int j = 11;//正确,编译时初始化
const int k;//错误,k是一个未经初始化的常量

const对象必须初始化

  • 初始化

    默认状态下,const对象仅在文件内有效

    //编译器会找到代码中所有用到size的地方,然后用128替换
    const int size = 128;
    

    编译器将在编译过程中把用到该变量的地方都替换成对应的值

  • 多个文件共享同一个const变量

    只在一个文件中定义一次const变量,在其他多个文件中使用extern关键字声明并使用它,不管是声明还是定义都添加extern关键字

    //a.cc定义并初始化了一个常量,该常量能被其他文件访问,定义一次
    extern const int size = 128;
    
    //a.h头文件中声明了size,与a.cc中的size是同一个
    extern const int size;
    

对const的引用

对常量的引用不能被用作修改它所绑定的对象

const int a = 11;
const int &r1 = a;//正确,引用及其绑定的对象都是常量
r1 = 22;//错误,对常量的引用不能被修改
int &r2 = r1;//错误,试图让一个非常量引用指向一个常量引用
  • 引用的类型必须与其所引用的对象的类型一致

  • 两个例外

    • 初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型

    • 允许一个常量引用绑定非常量对象、字面值、一般表达式

      int val = 11;
      const int &r1 = val;//正确
      const int &r2 = 12;//正确,常量引用
      const int &r3 = val * 2;//正确,常量引用
      int &r4 = val * 2;//错误
      
    • double val = 1.23;
      const int &r1 = val;//正确,如果r1不是常量,是非法错误
      //编译器把代码变成了下述形式
      const temp = val;//让双精度浮点数生成一个临时的整型常量
      const int &r1 = temp;//r1绑定这个临时对象
      

指针和const

主要分为两种情况:

  • 指向常量的指针:不能用于改变其所指对象的值,存放常量对象的地址

    const double a = 1.23;//a是一个常量,它的值不能改变
    double *p1 = &a;//错误,p1是普通指针
    const double *p2 = &a;//正确,p2指向一个double常量
    

    指针的类型必须与其所指对象的类型一致

    存在例外:允许用一个指向常量的指针指向一个非常量对象

    和常量引用一样,指向常量的指针没有规定其所指的对象必须是一个常量

    所谓的指向常量的指针仅仅要求不能通过该指针改变对象的值,而没有规定那个对象的值不能通过其他途径改变

  • 常量指针

    指针是对象,而引用不是

    允许把指针本身定位常量,常量指针必须初始化,而且一旦初始化完成,则它的值,即存放在指针里面的那个地址就不能再改变了

    int num = 0;
    int *const p = #//p将一直指向num
    const double num2 = 1.23;
    const double *const p1 = &num2;//p1是一个指向常量对象的常量指针
    

顶层const

  • 顶层const:指针本身是常量
  • 底层const:指针所指的对象是一个常量
int k = 11;
const int ci = 42;//不能改变ci的值,顶层const
int *const p1 = &i;//不能改变p1的值,指针本身是一个常量,顶层const
const int *p2 = &i;//能改变p2的值,指针所指的对象是一个常量,底层const
int const *p3 = &i;//能改变p3的值,指针所指的对象是一个常量,底层const
const int *const p4 = p2;//右边的是顶层const,左边的是底层const
const int &r = ci;//不能改变ci所指向的对象的值,是底层const

指针类型既可以是顶层const也可以是底层const

声明引用的const只能是底层const。

C++11之constexpr变量

  • 常量表达式

    是指不会改变并且在编译过程就能得到计算结果的表达式

  • constexpr变量

    在一个复杂系统中分辨一个初始值是不是常量表达式是很困难的。

    C++11中将变量声明为constexpr类型,由编译器来验证变量的值是否是一个常量表达式声明为constexpr的变量一定是一个常量,必须用常量表达式初始化。

    constexpr int i = 11;//11是一个常量表达式
    constexpr int j = i + 1;//i + 1是一个常量表达式
    constexpr int size = size();//只有当size()是一个constexpr函数时,声明才正确
    

    一般来说,如果确定定义的变量是一个常量表达式,就把他声明为constexpr类型

  • 指针和constexpr

    一个constexpr指针的初始值必须是nullptr或者0,或者是存储在某个固定地址中的对象;

    constexpr只对指针有效,与指针所指的对象无关

    const int *p1 = nullptr;//p1是一个指向整型常量的指针
    constexpr int *p2 = nullptr;//p2是一个指向整数的常量指针,constexpr把所定义的对象置成了顶层const
    

    一个是指向常量的指针,一个是常量指针

C++11之constexpr函数

是指能用于常量表达式的函数。

constexpr函数的几条约定:

  • 函数的返回类型及所有形参的类型都必须是字面值类型
  • 函数体中必须只有一条return语句
constexpr int new_size() {return 11;}
constexpr int a = new_size(); //正确,a是一个常量表达式

编译器把对constexpr函数的调用替换成其结果值,constexpr函数被隐式的指定为内联函数。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值