const 只对左边的有效,如果左边没有任何东西,对右边的生效,可以修饰指针,可以修饰指针指向的内容,可以修饰指针和指针指向的内容。
## 1、const 修饰函数参数
对于函数的入参,不管是什么数据类型,也不管是 指针传递,还是 引用传递,只要加了 const 修饰,就可以防止函数内意外修改该参数,起到保护作用。
比如下面的例子,给 a 和 b 加上const修饰后,如果函数内的语句试图修改 a 或 b,编辑器就会报出错误。
```cpp
void function(int* output, const classA& a, const classB* b) {
// do something
}
```
## 2、const 修饰函数返回值
用 const 修饰返回的指针或引用,保护指针或引用的内容不被修改。比如:
- int& GetAge()
- const int& GetAgeConst()
两者的区别在于:前者返回的是一个左值,其引用的内容可以被修改;后其引用的内容不可被修改。
## 3、const 修饰函数体
const 修饰函数体时,放到函数体的行尾处,表明在该函数体内,不能修改对象的数据成员,且不能调用非 const 成员函数。比如:
- void SetAge(int age)
- void SetAgeConst(int age) const
两者的区别在于:前者可以修改类的数据成员,而后者不可以。
```cpp
stu.SetAge(6); // 正确
stu.SetAgeConst(8); // 错误
```
- `T* const val;` 不能改变指针的值,可以改变指针指向对象的值
- `const T* val;` 不能改变指针指向对象的值,可以改变指针的值(即将指针指向另一个对象)
- `const T* const val;` 什么都不能做(实际还是可以做的)
static可以指向静态局部变量 静态全局变量、静态函数
data为私有方法 普通方法后面传递this指针 所以可以调用data
### static 作用:控制变量的存储放方式和可见性。
作用一:修饰局部变量:一般情况下,对于局部变量在程序中是存放在栈区的,并且局部的生命周期在包含语句块执⾏结束时便结束了。但是如果用static 关键字修饰的话,**该变量便会存放在静态数据区,其⽣命周期会⼀直延续到整个程序执⾏结束**。但是要注意的是,虽然⽤static 对局部变量修饰之后,其生命周期以及存储空间发了变化,**但其作用域并没有改变,作⽤域还是限制在其语句块。(也就是虽然它整个程序周期都存在,但是能访问到它的作用域还是哪个局部变量的作用域)**
作用二:修饰全部变量:对于一个全局变量,它既可以在本文件中被访问到,也可以在同一个⼯程中其它源⽂件被访问(添加 extern进⾏声明即可)。**⽤ static 对全局变量修饰改变了其作用域范围,由原来的整个⼯程可⻅变成了本⽂件可⻅。**
作⽤三:修饰函数:⽤ static 修饰函数,情况和修饰全局变量类似,也是改变了函数的作用域。
作⽤四:修饰类:如果 C++ 中对类中的某个函数⽤ static 修饰,则表示该函数**属于⼀个类而不是属于此类的任何特定对象**;如果对类中的某个变量进行static 修饰,则表示该变量以及所有的对象所有,存储空间中只存在⼀个副本,可以通过类和对象去调⽤。
作⽤五:类成员/类函数声明 static
函数体内 static 变量范围为该函数体,不同于 auto 变量,该变量的内存只被分配⼀次,因此其值在下次调⽤时仍维持上次的值;
在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
在模块内的 static 函数只可被这⼀模块内的其它函数调⽤,这个函数的使⽤范围被限制在声明它的模块内;
在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
在类中的 static 成员函数属于整个类所拥有,**这个函数不接收this 指针,因⽽只能访问类 的 static 成员变量。 static 类对象必须要在类外进⾏初始化, static 修饰的变量先于对象存在,所以 static 修饰的变量要在类外初始化;**
由于 static 修饰的类成员属于类,不属于对象,因此 static 类成员函数是没有 this 指针, this 指针是指向本对象的指针,正因为没有this 指针,**所以 static 类成员函数不能访问⾮ static 的类成员**,只能访问 static修饰的类成员;
static 成员函数不能被 virtual 修饰, static 成员不属于任何对象或实例,所以加上 virtual没有任何实际意义;静态成员函数没有 this 指针,虚函数的实现是为每⼀个对象分配⼀个 vptr 指针,⽽ vptr 是通过 this 指针调⽤的,所以不能为virtual;虚函数的调⽤关系,this->vptr->ctable->virtual function。