【C++】 const类型总结和赋值判断

关键词const是什么含义?

const是只读变量,意味着不能对变量进行写入操作。

const int a;  //a为常量
int const a;  //a为常量
const int *a; //a为普通指针,指向的是const常量
int * const a; //a为常量指针,指向的是普通变量
int const * a const; //a为常量指针,指向的是const常量

本质:const在谁后面谁就不可修改,const在最前面则将其后移一位即可,二者等效

因为const变量一经初始化就不能被更改,所以const对象必须要初始化。该特征仅在执行改变操作时发生作用,其他如赋值、算术运算时根本无须在意它是不是一个常量。

一般const对象仅在文件内有效,如果需要多个文件共用,需要在声明和定义都添加上extern关键字。

//在file1.cpp定义并初始化,该变量能被其他文件访问
extern const int buffSize = 5;
//在file1.h头文件
extern const int buffSize;
1.对const的引用
const int ci = 1024;
const int &r1 = ci;  //正确,引用和其对象都是常量
int &2 = ci;   //错误,试图让一个非常量引用指向一个常量对象  

int i = 42;
const int &r1 = i;  //允许const int&绑定到一个普通int对象上

常量引用仅仅对引用可参与的操作作出了限定(不允许更改),对其引用对象本身是不是const并未规定。因此对象有可能是一个正常变量,但是不能通过引用(别名)去改变他。i可以通过其他途径去改变,比如i = 5这种,这种是没规定的。

2.指针和const
const double pi = 3.14;   //常量,值不可变
double *ptr = π        //错误,不能用普通指针指向常量
const double *cptr = π //正确
*cptr = 42;               //错误,不可更改

允许令一个指向常量的指针指向非常量对象,但不能改变该常量的值,和引用类似。所谓指向常量的指针仅仅是要求不能通过该指针取改变常量的指,但没有规定不能用其他途径去改变。指向常量的指针或引用,不过是指针或引用“自以为是”,觉得自己指向了常量,所以自觉地不去改变所指对象的值。

double pi = 3.14;
const double *cptr = π //正确

3.const指针

指针和引用不一样,指针是对象,因此可以将指针本身定为常量。常量指针(const pointer)作为一个const类型,必须初始化,而且一旦完成初始化,则它的值(即指向的地址)就无法改变。下面代码初始化了一个指向int的常量指针,const放在curErr前面,说明curErr是个常量。常量指针只是说我一定会指向errNumb而不会发生改变,但是errNumb是可以发生改变的,因为它是个普通int变量。

int errNumb = 0;
int *const curErr = &errNumb;
    *errNumb = 0;//正确

但是如果常量指针指向的是常量,那两个都不能发生变化。如下所示errNumb是一个常量,curErr指向errNumb,不能通过*errNumb去改变他的值。

const int errNumb = 0;
int *const curErr = &errNumb;
    *errNumb = 0;//错误

4.顶层const

指针本身是不是常量以及指针所指的是不是一个常量,这是两个独立的问题。用名词顶层表示指针本身是一个常量,而名词底层表示指针所指的对象是一个常量。
更一般的,顶层const可以表示任何的对象是常量,而底层const主要用于指针和引用等符合类型。

int i = 0;  
int *const p1 = &i;    //不能改变p1的值,这是个常量指针,顶层const
const int ci = 42;     //单独一个,没有符合类型,本身就是顶层const
const int *p2 = &c1;   //指针不是常量,指向的int是常量,指向对象为底层,这是底层const
const int *const p3 = p2; //靠左的是所指对象,是底层const,靠右的是指针,是顶层const
const int &r = ci;     //引用的是常量int,都是底层const

执行拷贝操作并不会影响被拷贝对象的值,因此,拷入和拷出的对象是否是const都没什么影响。顶层const不受什么影响,因为它们代表的是自身是否const。

i = ci;  //ci是顶层const,对拷贝操作不影响
p2 = p3;  //p2和p3都是指向const int,因此可以拷贝。至于p3顶层const不影响。

对于底层const来说,拷贝并不是每次都可接受,它们必须具备相同的底层const资格,即指向的变量必须我相同类型。非常量可以转换常量,反之则不行。通俗来说,就是花心的人可以变成专一的人,但是专一的人,一直得保证是专一的。

int *p = p3;  //错误,p3具有底层const,即指向的是const int,但是p没有,不能让非常量转换为const变量
p2 = p3;      //正确,p2和p3都是底层const
p2 = &i;      //正确,i是普通变量,p2指向的是const变量,普通变量可以转换const变量
int &r = ci;  //错误,ci是const变量,不能转换为int普通变量
const int &r2 = i; //正确,i是普通变量,可以转换为const变量

总结:存在指针的变量赋值问题,可以忽略顶层const,要关注底层const,主要就是指针所指向的对象。把const变量转换为普通变量,是不可接受的。把普通变量转换为const变量是可接受的。

const变量好处:
1.给阅读代码的人看到,可以有效理解变量的含义。
2.保护某些变量被无意修改,产生不必要的bug。

《C++ Primer 中文版 》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值