首先我们需要一下const关键字的定义,const名叫常量限定符,当const修饰变量时,就是在告诉编译器该变量只可访问不可修改,而编译器对于被const修饰的变量有一个优化,编译器不会专门为其开辟空间,而是将变量名和数值作为一个kv键值对存入到符号表中。
注意:const修饰的变量必须要在定义时初始化
如上,当我们想要通过指针改变a时发现无法改变,这就是因为编译器对其的优化,导致a为存入符号表的一个固定值,而&a和b的地址一样只是编译器想让我们看到的,实际上是取地址时,编译器又开了一块空间存储a的值,并将这个空间地址给b。
通过volatile关键字修饰变量我们可以告诉编译器,该变量无需优化
如上所示
一,const常见用法
1.1 const修饰变量
const int a=10;
int const a=10;
const修饰变量如下,该变量无法直接修改,但是可以通过指针进行修改
1.2 const修饰指针
const修饰指针以*为界限分为常量指针、指针常量,也就是我们经常说的左定值,右定向
常量指针
const在*号左边,指针所指向的值无法改,但是可以改变指针的指向
指针常量
const在*号右边,指针所指向的值可以修改,但是无法更改指针的指向
以及两者共存的情况 ,无法修改指针指向的内容,也无法修改指针的指向
1.3 const修饰类成员变量
const修饰类成员变量,该变量必须要在初始化列表初始化,初始化之后该变量无法在更改,即使是构造函数也无法修改
class example
{
public:
example(int a=10)
:_a(a)
{
//_a = 11;//无法修改,会报错
}
private:
const int _a;
};
1.4 const修饰类成员函数
const修饰成员函数使用格式如下
class example
{
public:
example(int a=10)
:_a(a)
{}
void Example() const;
private:
int _a;
};
实际上const修饰的是Example成员函数隐藏的*this指针,因此其实际修饰格式如下
class example
{
public:
example(int a=10)
:_a(a)
{}
//void Example() const;
void Example(const example* this);
private:
int _a;
};
因此当const修饰成员函数时,该函数对于对象的成员变量只能读取不能修改
1.5 const修饰函数返回值
const修饰函数返回值,则函数返回值被赋值对象必须也被const所修饰,通常返回值与引用搭配
const int& example();
const int a=exampel();//正确
int a=example();//错误
二、const实战常用用法解析
2.1 const修饰函数输入式参数
const修饰输入式参数指的是,当我们函数的某个参数只希望函数内部读取而不能修改,就可以使用const进行修饰
例如上面所示,STL库中的strcmp函数,比较两个字符串是否相等,因此无需对其进行修改,为了保护参数就可以用const进行修饰
2.2 const修饰类成员函数
当类成员函数只需访问类成员变量,如打印成员变量之类,此时就可以用const修饰,防止误改成员变量
如上图STL中的vector容器,重载[]访问数组元素的接口,就有为了保证成员变量不被改变而const修饰成员函数的操作
2.3 const修饰函数返回值
如上图所示,注意vector中重载[]的第二个接口的返回值const_reference,而该类型实质上是const value_type&,注意这个引用,后面要考。
首先当我们选择引用返回相比于正常返回,中间减少了数据拷贝——临时变量——数据拷贝的过程,有效提升了返回效率。而引用返回也有其弊端,如果用户修改这个返回值,那么就会直接影响容器中对应的值,如果我们不想让用户随意修改容器中的数据又想要高效的引用返回,那么就需要用const修饰返回值