一、const关键字
const修饰的变量,其值存放在只读数据段中,其值不能被改变。
1.定义普通变量
时,我们便可通过添加const来创建一个不能被修改的常量,下方两种写法都可
const int num1 = 10;
int const num1 = 10;
2.const和 * 结合
const int *a = new int; //1
int const *a = new int; //2
int * const a = new int; //3
const int *const a = new int; //4
那么上列的四行代码,究竟是把谁变为只读量呢?
我的方法是看 const * 变量 三者谁靠在一起,const永远把自己右侧的变为只读,像是一个英语中的副词,依附在自己右侧的变量身上,然后如果*和变量靠在一起就优先算做一个整体
①首先来看//1的代码,*a靠在一起算作一个整体,那么const就把*a这个整体变为只读,*的意思是取值,*a放在一起就是a这个地址里存放的值,也就是说我后面的代码不能改变a所存地址中的值,这时候如果我运行
*a = 10
a = &b //b与a为同类型指针
系统便会提示第一行报错,第二行则没有问题
②然后来看//2的代码,他比起//1,只是把int和const互换了位置,*和a依旧靠在一起,const依旧修饰他们这个整体,也就是说代码的整体功能没有发生改变,只是两种代码风格。
③//3中,*和a没有靠在一起,const在中间修饰右侧的a,a是什么呢?a是个指针,说白了就是一串地址。那他的意思就是a带表的地址不能变,该地址所存放的值,也就是*a确是可以变化的这个时候如果我运行
*a = 10
a = &b //b与a为同类型指针
那么便会提示第二行报错,第一行则没有问题
④//4中,*和a没放在一起,我们先看右侧的const,因为左侧的const的右侧是个*,单独一个*没什么意义
右侧的const在a前修饰,也就是指针本身已经不能改变了,const修饰过a后和a作为一个整体,理解为在a前加了个副词,从(a)变成了(只读的a)
然后左侧的const再来修饰[*+(只读的a)]这个整体,也就是说(只读的a)这个地址中的值也不能变,这时候如果运行
*a = 10
a = &b //b与a为同类型指针
会发现系统会提示两者都错
3.const在类中的应用
1)内部函数
class Entity
{
private:
int num1,num2;
public:
int ADD() const
{
return num1;
}
};
我们先定义了一个名为Entity的类,如果向上方一样在类函数中加上const,则它代表的含义则是,承诺该函数不会对类进行改变,也就是类中定义的num1和num2都不可以被改变。
这时候如果我试图在ADD函数内加上一行类似 num1 = 1 这种,便一定会报错。
2)指针结合
现在我们把指针也结合到类中,我们把两个私有变量都改为指针
class Entity
{
private:
int* num1,*num2;
public:
const int* const ADD() const
{
return num1;
}
};
首先我们定义了一个不会改变类的内部函数,然后该函数执行后的返回值为指针类型,该指针以及该指针所映射的值都不会被改变,
4.const和&结合
&和*的的区别还是很大的,用不了上面那套记法
现在我写一段代码
class Entity
{
private:
int num1,num2;
public:
intADD() const
{
return num1;
}
};
int main()
{
Entity E;
}
void function(const Entity& E)
{
std::cout << E.ADD() << std::endl;
}
这段代码中在引用前加了const,我的引用就是把E这个类直接拿过来用,const就意味着不让引用过来的E发生变化,因为这可能会牵连很多东西。
我在function函数中调用了E中的内置函数ADD(),如果此时我把内置函数(绿色的)中的const如果去掉,可能就会导致我们的function用不了,因为我在设置它的时候保证不改变E,但是我现在却用了一个E内部一个不保证不改变E的函数,所以便会报错。
所以在类的设置中,那些本就不对类进行改变的函数一般都要加上 const
二、static 的几种用法
1.作用在变量上(内存分配:全局数据区)
1.1全局变量
static如果作用在全局变量身上后,称他为静态全局变量,那么该变量只能在该文件中使用,其他文件可以出现同名变量,链接器并不会再把它连接到这个文件以外的代码上。在一个文件中,功能上和普通全局变量完全相同。但是如果想在多个文件中用该变量,则不能使用静态全局变量。
1.2局部变量
static如果作用在局部变量身上后,称他为静态局部变量,他不跟其他局部变量一样分配在栈中,
该变量在程序第一次执行到声明处时被初始化,后续调用函数则不会再被初始化,也就是会保留函数上次执行结束后的值。
如果一个函数运行和它以前的运行结果有关,那么一般我们就会使用静态局部变量。也可以用来统计函数执行次数。它的作用域
1.3类的成员变量
static如果作用在类的成员变量身上后,称他为静态成员变量。静态成员变量为该类所有对象共有,在一个实例中改变值,在其他实例调用时都是改变后的值。
因为他是所有所有对象共有,所以它不需要通过对象,通过类的类型就能访问。
<类类型名>::<静态数据成员名>
2.函数
2.1普通函数
在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,跟静态全局变量一样,允许其他文件中有重名函数,它只能在声明它的文件当中可见,不能被其它文件使用。
2.2类的成员函数
static如果作用在类的成员函数身上后,称他为静态成员函数。
静态成员函数不能访问非静态成员函数和非静态成员变量,仅可以访问静态成员变量、静态成员函数。