一 .const关键字与最基本性质。
定义一个常量:
const int bufferSize = 512
需要注意的是:
const int bufferSize = 512;
bufferSize = 10; // 错误 常量不能改变 也就是说常量只能作为右值
//上面代码与下面相同
int a =10;
bufferSize = a; //错误
//const int k; //错误 常量因为被初始化后不能被改变,所以必须初始化。
常量仅仅在它被执行改变自己的时候起作用。
在多个文件中需要用到同一个常量时,可以用关键字extern让常量共享。
二.const的引用。(常量必须用常引用)
可以把引用绑定到const对象上面,称为对常量的引用,或成为常量引用。结合const性质,我们可以分析到对常量的引用,则不允许此引用改变这个值。
const int a=100;
const int &newa = a;//正确 newa是对常量a的引用
int a=100;
const int &newa = a; //允许常量对非常量的引用,这样情况只会让newa无法修改a的值
newa=10; //错误 newa是一个常量引用,他不能改变a的值。但是不会阻止其他方法修改a的值
//上面将常量对非常量的引用是不可逆的,也就是不能让非常量对常量引用,如果可以,很明显就可以修改值。此点切忌
三.指针和const
3.1 指向常量的指针
与引用一样,也可以让指针指向常量或者非常量。也就是指向常量的指针不能通过指针来改变指向对象的值。要想存放常量对象的地址,只能使用指向常量的指针。
const int a=100;
int *ptr = &a; //错误
const int *p =&a; //正确
*p = 10; //错误。不能通过指针改变指向常量的值
与前面讨论类似,运行一个指向常量的指针 去指向一个非常量对象。此时和上面代码功能类似,指向常量的指针就是意味着不能通过指针来改变指向对象的值。
int b =10;
const int *ptr =&b;//正确
*ptr = 100; //错误
b =100; //正确
3.2 const指针
const指针 顾名思义 常量指针 。因为指针是对象而引用不是。允许把指针本身定为常量。常量指针同理必须被初始化,
同时按照理解,常量指针。指针是指向对象的,它的空间是存储指向对象的地址。此时因为它变为了常量指针,在初始化后不能改变,也就是说常量指针只能指向一个对象,不能改变。
int a=100;
int *const p = &a; //正确 常量指针指向a
*p =10; //正确 此时可以用过常量指针改变a的值,因为常量指针限制了指针不能修改,没有限制
//指针指向的对象的值
cout<<"a = "<<a<<endl;// a =10
int a=100;
int *const p = &a; //正确
int b= 100;
p=&b; //错误 //常量指针只能指向一次。不能修改指向
四.顶层const
指针本身是不是常量指针和指针指向的内容是不是常量是两个相互独立的问题。用名称 顶层const(top-level-const) 表示指针本身是一个常量,底层const(low-level-const)表示指针所值对象是一个常量。
更一般的说,顶层const表示的是任何的对象是常量。对任何数据类型都试用。底层const则与指针和引用等复合类型的基本类型有关。特殊的是指针既可以是顶层也可以是底层。所有的引用都是底层const。
int i= 0;
int *const p1 = &i; //顶层const 不允许改变p1
const int ci =42; // 顶层const 不允许改变ci
const int *p2 = &ci; //底层const 允许改变p2
//方法:只看const修饰的对象是否是常量 是常量则为顶层,否则为底层
顶层const 底层const主要的区别:
顶层const在对象之间的拷贝时,不印象。因为顶层const是一个常量,它在拷贝时,不会修改之间信息。所以不影响。
底层const在拷贝的时候,就必须要求两个对象之间拥有相同的底层const。(非常量可以转化为常量,可以相互转化的类型)
五.了解constexpr和常量表达式
常量表达式是要求在编译阶段就能计算得到结果的表达式。用常量表达式初始化的const对象也是常量表达式。
const int max = 0; //是
const int newmax = max +1; //是
int suff = 127; //不是
const int buffer = getsize(); //不是
有constexpr的原因是在开发过程中,发现常量的初始值并非是常量表达式的情况。所以影响了常量的初始化。C++11允许使用关键字constexpr 定义常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化。
constexpr int number = 20; // 正确
constexpr int size = getsize(); // 只有当getsize()是一个constexpr函数时,是正确的。
此处指针部分没有讨论。