C++中引用和指针有关const限定符的区分

 

指针和引用:

总结自C++ Primer,仅供自己学习参考

引用:

  1. 引用本身只是目标对象的一个别名,自己本身并不是对象

  2. 变量引用可以间接对变量进行修改

  3. 常量别名代表的只能是常量,如果常量别名一个变量,也是先通过创建一个临时量,然后对这个临时量创建别名

  4. 变量别名不能指向一个常量,也不能指向运算后的值后的结果,e.g.

    int pi = 3;
    const int PI = 3;
       
    //当对象为变量时
    int &revPI = pi;  //正确,变量的别名代表的是一个变量
    int &revPIt = pi *2; //错误,不能指向变量运算后的结果(即返回的是一个常量值)
    const int &cRevPI = pi; //正确,常量别名可以指向一个变量,通过临时量代替
       
    //当对象为常量时
    int &cstRevPI = PI; //错误,变量别名必须指向一个变量
    const int &cstcRevPI = PI;//正确,常量别名可以指向一个常量
    
  5. 引用在decltype出并非是对象的同义词,而表示的是对应类型的引用

    const int ci = 0, &cj = ci;
    decltype(ci) x = 0; //x的类型是const int
    decltype(cj) y = x; //y的类型是const int&,必须要设定为一个const int的引用
    decltype(cj) z; //错误,缺少引用代表的对象
    

    而对于表达式,在使用decltype关键词的时候,由于表达式本身可以返回一个值,所以会被识别为一个引用类型

    int i = 0;
    decltype((i)) d; //错误,d是一个int&,需要初始化
    decltype(i) e; //正确,e是一个int,没有初始化
    

指针:

  1. 指针本身是一个对象,其含义为指向目标对象的地址
  2. void指针可以指向任意一种变量代表的地址
  3. 常量指针必须初始化,其中通过const关键词有两种表达意思:
    • int *const ptr指的是常量指针,地址不可改变,指向一个int类型的变量
    • const int *ptr指的是常量的指针是常量类型,地址可改变,指向的是const int类型的常量
  4. 对于*const关键词修改的指针,虽然地址不能改变,但是依旧可以通过这个指针修改对应变量的值

对于const限定符

顶层const:指针本身是一个常量

底层const:指针所指的对象是一个常量

  • 对于顶层const中,在常量对象中的拷贝操作几乎不受什么影响

  • 对于底层const中,只有两个对象有相同的底层const才能进行拷贝操作,举例如下:

    const ci = 42;
    const int *const cptr = &i;
      
    const int *cptr2 = cptr //正确,因为*cptr2和*cptr指向的都是常量的指针
    int *p = p3; //错误,因为*p不是指向常量的指针,所以不能拷贝p3
    

    其中对于引用也同样成立:

    const int ci = 42;
      
    int &r = ci;  //由于ci本身是常量,和&r代表的底层const不同,所以错误
    const int &r2 = ci; //正确,底层const相同