static 与 const
static:
用于控制变量的存储方式 与 可见性
1.变量:
静态局部变量:
初始值 | 作用域 | 生命周期 | 存储区域 |
---|---|---|---|
由用户自己定义 | 所在语句块 | 整个程序结束 | 静态数据区 |
在函数的中的静态局部变量:只有初次调用函数时,才会进行初始化。在每次调用函数时,都是根据上次调用的值进行操作。
void Funtion(){
static int x=0;
int y=0;
x++;
y++;
将 x 与 y 输出
}
int main(){
Funtion();//x=1,y=1
Funtion();//x=2,y=1
}
在类同样可以:
class Temple{
public:
static Temple& Get(){
static Temple temple;// 第一次调用时,会生成一个类对象
return temple;
}
}
int main(){
Temple t1=Temple::Get();// 获得一个类对象,第一次调用会初始化
Temple t2=Temple::Get();// t1与t2是同一个对象
}
静态全局变量:
初始值 | 作用域 | 生命周期 | 存储区域 |
---|---|---|---|
由用户自己定义 | 仅本文件可以见 | 整个程序结束 | 静态数据区 |
2.类外函数:
作用域:仅本文件可以见
3.类内成员变量:
该变量属于整个类,对类的所有对象都只有一份拷贝,不属于任何特定的类对象。所有类共用一个数据。
只能在类外进行定义,类中只是声明。
class P{
static int x;
}
int P::x;// 类外定义
int main(){
P p1;
p1.x=10;
P p2;
p2.x=20;// p1与p2的x都会修改
P::x=10;// p1与p2的x都会修改
}
4.类内成员函数
1、该函数只能调用静态成员变量,不能使用非静态的成员变量。
因为类中的非静态成员函数会根据当前的类实例来构建,但静态成员函数是不依赖于特定的类实例,也就是静态成员变量没有this指针,也就无法访问非静态成员变量,因为访问非静态成员变量需要this指针。
2、不能是虚函数
class P{
static int x;
int y;
static int Print1();// 声明
int Print2(){
x++;
y++;
}
}
// 静态成员函数在类外实现更加规范。
int P::Print1(){// 由于没有this指针,所以无法确定y的值
x++;// 不会报错
y++// 会报错
}
int Print1(P p){// 本质上与Print2是相同的
p.x++;
p.y++;
}
const
表明该变量为常量,不可修改
1. 基本类型及数据结构
const int a=5;// 效果一样
int const b=6;
2.指针变量
此时const放置的位置有讲究
1、const放在 * 前时,代表这个指针所指的是常量,指针本身可以被改变,指向哪个常量可以改变,但必须是常量。不可以修改指针所指的数据
const int* a=5;
const int b=6;
a=&b;// OK,指向另一个常量
*a=6;// error,不可以修改指针所指的值
int const* c;// 与a是相同的效果
2、const在 * 后时,代表该指针是常量,即该指针存放的地址不变,始终指向同一个地址,指针本身不可改变,而这个地址所存放的数据可以改变
int* const a=new int;
*a=5// OK,可以修改地址存放的数据
int b=6;
a=&b;//error,不能修改指针本身
3、 const 在 * 的前后时,指针本身不变,指针所指的数据不变
3.引用
注意,与指针不同是,引用没有指针本身与指针所指的内容。引用就是内容,就是变量本身
int a=5;
const int& b=a// 等价与 const int a
4.函数
1、传入的参数带有 const:就按照 变量加上const进行处理,判断哪些不能修改
常用于 参数为指针与引用时
void function(const int& a)// 常量引用,常用于只读
2、返回值带有const:返回值有const修饰
const int* function(){
int* a=5;
return a;// 返回后的值带有const修饰
}
const int* const function()// 返回一个指针本身与所指数据都不变的指针
5.类中的使用(与static区分开)
1、成员变量:
该变量只是在类实体中是常量,而在不同类对象中可以有不同的值。
对static不同的:
1.在类的声明中,不能初始化。只能使用构造函数进行初始化
2.const类变量有多份存储,而static只有一份拷贝。
2、成员方法:
在方法后面添加const
目的:防止该成员方法对成员变量进行修改,在里面不能修改成员变量
class Example{
int a;
int GetA() const{
a=4;// error,const成员函数不能修改成员变量
return a// OK,可以访问
}
};
若实在要修改,可以在成员变量前加上 mutable
class Example{
mutable int a;
int GetA() const{
a=4;// OK
return a// OK,可以访问
}
};
3、类对象:常量对象
常量对象只能调用 const成员函数,不能调用非常量。
非常量对象都可以调用
原因:成员函数的参数中隐含了 this指针( class* const this).
若类对象加上 const,则this指针变为const class* const this,此时就无法修改类对象的各种参数
class Example{
int a;
int GetA1() const{
return a;
}
int GetA2() {
return a;
}
};
int main(){
Example e;
e.GetA1();// OK
e.GetA2();//error
}