const的位置
//****************************整型常量**************************
const int a=1;//必须赋初始值
int const b=2;//必须赋初始值;完全等价于 const int b=2;
//const int c; int const d;//错误;必须有初始值
//a=9+3; b=12;//不允许再进行赋值
//***********************常量指针*****************************
int s=12;
const int *iptr;//常量指针;可以不赋初始值
/*const修饰的是int,而int定义的是一个整型值。
因此*iptr所指向的对象的值不能通过*iptr来修改,
但是可以重新给iptr来赋值,使其指向不同的对象*/
iptr=&a;
iptr=&b;
iptr=&s;
//*iptr=123;错误。
//常量指针与普通指针的区别只有一个,就是不能通过*ptr来间接地修改s的值。
//********************指针常量*********************
int* const ptr=&s;//指针常量(想想整型常量);必须赋初始值;且初始值赋&a后&b都是错误的
/*const修饰的是ptr,ptr代表的是一个指针地址,
因此不能赋给ptr其他的地址值,但可以修改ptr所指向的值*/
//ptr=&s;//指针不允许再赋值
*ptr=123;//成功。
//指针常量与整型常量的差别:可以通过*ptr来间接地修改s的值
const和指针
const也可以和指针变量一起使用,这样可以限制指针变量本身,也可以限制指针指向的数据。const和指针一起使用会有几种不同的顺序,如下所示:
const int *p1;
int const *p2;
int * const p3;
在最后一种情况下,指针是只读的,也就是 p3 本身的值不能被修改;在前面两种情况下,指针所指向的数据是只读的,也就是 p1、p2 本身的值可以修改(指向不同的数据),但它们指向的数据不能被修改。当然,指针本身和它指向的数据都有可能是只读的,下面的两种写法能够做到这一点:
const int * const p4;
int const * const p5;
const 和指针结合的写法多少有点让初学者摸不着头脑,大家可以这样来记忆:const 离变量名近就是用来修饰指针变量的,离变量名远就是用来修饰指针指向的数据,如果近的和远的都有,那么就同时修饰指针变量以及它指向的数据。
const的修饰对象
看到const 关键字,C++程序员首先想到的可能是const 常量。这可不是良好的条件反射。如果只知道用const 定义常量,那么相当于把火药仅用于制作鞭炮。const 更大的魅力是它可以修饰函数的参数、返回值,甚至函数的定义体。
const输入参数
如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加 const 修饰,否则该参数将失去输出功能。const 只能修饰输入参数。
如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const 修饰。
“引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可,因此函数最终成为void Func(const A &a)
const通常用在函数形参中,如果形参是一个指针,为了防止在函数内部修改指针指向的数据,就可以用 const来限制。
const返回值
如果给以“指针传递”方式的函数返回值加const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。
函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。
const成员变量
- static const int b=234;//只有静态常量变量才可以在类中初始化
- 类的const常量只能在初始化表里被初始化,因为它不能在函数体内用赋值的方式来初始化
- 类中的常量:怎样才能建立在整个类中都恒定的常量呢?别指望const数据成员了,应该用类中的枚举常量来实现。例如
class A
{…
enum { SIZE1 = 100, SIZE2 = 200}; // 枚举常量
int array1[SIZE1];
int array2[SIZE2];
};
枚举常量不会占用对象的存储空间,它们在编译时被全部求值。枚举常量的缺点是:它的隐含数据类型是整数,其最大值有限,且不能表示浮点数(如PI=3.14159)。
const成员函数
声明:<类型标志符> 函数名(参数表)const;
- const是函数类型的一部分,在实现部分也要带该关键字。Eg:int A::getValue() const {}
- const关键字可以用于对重载函数的区分。
- 常成员函数不能更新类的成员变量,也不能调用该类中没有用const修饰的成员函数,只能调用常成员函数。