首先我们来看一下为什么要使用const呢?因为采用符号常量写出的代码更容易维护;指针常常是边读边移动,许多函数参数都是只读不谢的,const最常见的用法就是作为数组的界和switch分情况标记(也可以用枚举符代替)。
分类:
常变量:const 类型说明符 变量名
常引用: const 类型说明符 & 引用名
常对象:类名::fun(形参) const
常数组:类型说明符 const 数组名[大小]
常指针:const 类型说明符* 指针名 ,类型说明符* const 指针名
注意:在常变量(const 类型说明符 变量名)、常引用(const 类型说明符 & 引用名)、常对象(类名 const 对象名)、常数组(类型说明符 const 数组名[大小]),const”与“类型说明符”或类名(其实类名是一种自定义的类型说明符)的位置可以互换
比如:const int a = 5;与int const a = 5;等同
类名 const 对象名 与 const 类名 对象名 等同
1、用法1:常量
取代了c中的宏定义,声明时必须进行初始化(c++中则不然)。const限制了常量的使用方式,并没有描述常量应该如何分配。如果编译器知道了某const的所有使用,它甚至可以不为该const分配空间。最简单的常见情况就是常量的值在编译时已知,而且不需要分配存储。
用const声明的变量虽然增加了分配空间,但是可以不保证类型安全。
c标准中,const定义的常量是全局的,c++中视声明位置而定
2、用法2:指针和常量
使用指针时涉及到两个对象:改指针本身和被它所指的对象而不是使这个指针成为常量。要将指针本身而不是被指对象声明为常量,必须使用声明运算符*const
所以出现在*之前的const是作为基础类型的一部分,
char* const cp;//到char的const指针
pc不能指向别的字符串,但可以修改其指向的字符串的内容(指向不能变)
char const *pc1;//到const char的指针
内容不能改变,可以改变指向
const char* pc2;//到const char 的指针(后两个声明是等同的)
内容不能改变可以改变指向
从右往左读的记忆方式:
注意:
允许把非const对象的地址赋给指向const对象的指针,不允许把一个const对象的地址赋给一个普通的、非const对象的指针
3、用法3:const修饰函数传入参数
将函数传入参数声明为const,以指明使用这种参数仅仅是为了效率的原因,而不是想让调用函数能够修改对象的值。同理,将指针参数声明为const,函数将不修改由这个参数所指的对象,通常修饰指针参数和引用参数:
void Fun(const A * in);//修饰指针型传入参数
void Fun(const A& in);//修饰引用型传入参数
4、用法4修饰函数返回值
可以组织用户修改返回值,返回值也要相应的付给一个常量或常指针
5、用法5:const修饰成员函数(c++特性)
const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数
const对象的成员是不能修改的,而通过指针维护的对象确实可以修改的
const成员函数不可以修改对象的数据,不管对象是否具有const性质。编译时以是否修改成员数据为依据进行检查。
具有展开来说:
(一)常量与指针
常量与指针放在一起很容易让人难以区分,,对于常量指针和指针常量也不是所有学习c/c++的人都能说清的:
例如:
const int *m1 = new int(10);
int * const m2 = new int(20);
const 到底是修饰指针还是修饰指针指向的区域呢:实际上const只对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符,那么它才对右边的东西起作用,根据这个规则来判断,m1应该是常量指针(不能通过m1来修改它指向的内容),而m2应该是指针常量(不能让m2指向其它的内存模块)