关键字const用来定义常量,如果一个变量被const修饰,那么它的值就不能再被改变。
const的存在一定有它的合理性,const修饰符有以下的优点:
- 预编译指令只是对值进行简单的替换,不能进行类型检查
- 可以保护被修饰的东西,防止意外修改,增强程序的健壮性
- 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
1. const修饰普通变量
表示:变量值不能被改变了。
用const修饰变量时,一定要给变量初始化,否则之后就不能再进行赋值了。
const int n=5;
int const n=5;
2. const修饰指针
区分常量指针和指针常量,以星号为分界线:
const在星号的左边,则为常量指针;》》》int const * n
// 常量指针是指针指向的内容是常量,可以有一下两种定义方式。
const int * n;
int const * n;
const在星号的右边,则为指针常量;》》》int *const n
3. const修饰成员变量
const修饰类的成员变量,表示成员常量,不能被修改,同时它只能在初始化列表中赋值。
class A {
…
const int nValue; // 成员常量不能被修改
…
A(int x): nValue(x) { }; // 只能在初始化列表中赋值
}
4. const修饰成员函数
将const修饰的“成员函数”称之为const成员函数。this指针的类型是:类类型* const this,即成员函数中,不能修改this指针,但是其所指向对象的成员变量可以被修改,const修饰类成员函数,实际上就是将this限定为:const 类类型 * const this,表明在该成员函数中不能对调用对象的任何成员进行修改,起到保护对象的作用。
格式: 将const关键字放在函数的括号后面
class Date {
public:
void Display()const {
cout<<_year<
}
//该成员函数实际上是这样
/*
void Display(const Date *const this)
{
cout<_year<
}*/
private:
int _year;
int _month;
int _day;
};
5. const修饰函数参数
(1)const修饰普通函数参数
void function(const int Var);
这表示形参不会发生改变,但实际上这是没有意义的,因为我们通常是为了保证外部的实参数据不发生变化,这里形参实际上是实参的拷贝,实参本来就不会发生变化。
(2)const修饰函数指针参数
void function(const char* Var);
// 我们把外部实参的地址赋值给用const修饰的指针形参,这样我们就无法通过指针修改其所指的外部实参,保护了数据的安全性。
但如果是这种const指针形参就毫无意义:
void function(char* const Var);
// 因为这表示指针形参不会改变,但是我们依然可以通过指针修改传过来的外部实参,无法保证外部数据的安全性
(3)const修饰函数引用参数
void function(const Type& Var); // 引用参数在函数内不可以改变
// 参数为引用,将外部实参传递给引用形参,传递的是外部实参本身,无需进行拷贝,增加了效率,同时参数是const引用,无法通过引用修改实参,保证了外部数据的安全性。
6. const修饰数组
数组变量实际上就是const的指针,所以不能直接赋值:
const int a[]
// a---->const int * const a;
// const修饰数组表明数组的每个元素都是const int,无法修改,所以必须通过初始化进行赋值,否则写出来后就无法进行赋值了。
7. const 修饰函数返回值
const修饰函数返回值其实用的并不是很多。
总结
1、const对象只能调用const成员函数、不能调用非const成员函数;
2、非const对象可以调用const成员函数。