const 分为三种介绍
-
普通const对象(变量) 一旦创建就不能再改变,所以const的对象必须要初始化,必须赋值,不然没有意义(难道不可更改一个没有的东西)
这里插播一个define,虽然# define a 30;也是让a不可更改,但是他是替代,出现几次替代几次。产生多个副本,const只有一个副本,define不能定义数据类型 -
对于类里面的const我们分为四种
- const成员变量(只读),和普通的const变量一样,定义的时候在前面加上const关键字就可以,初始化const成员变量只有一个方法,就是参数初始化表(构造函数初始化),所以不同的对象const的数值不一样。这和static的类外初始化非常不同,const static 和static const都是类外初始化
- const成员函数为了保护数据设置,可以使用类中的所有成员变量,但是不能修改变量,语法就是在声明和定义的时候在函数头部的结尾加上const关键字,const成员函数不能调用类中非const的成员函数
double getprice() const;
- const对象,常对象只能调用类中的常成员函数(const的对象只能调用const的函数),常对象就是不能对当前对象的成员进行修改,进行左值操作
const 类名 对象名(实参名); const Book a(a);
类名 const 对象名(实参名);
- 对象的const引用,将对象作为函数的参数时,常常采用引用的方式作为函数的参数,为了避免对对象本身做修改,在函数形参前加上const关键字
- const指针:注意 * 在const的前面还是后面,* 在const之前说明指针是一个常量,这样不变的就是指针本身的值(地址)而不是指针指向的值(简单一句话就看离对象名最近的是const还是*)
int a = 0;
int * const p = &a;//p是一个常量指针,不能更改,也就是不能进行p++这种操作
const int *p;//p是一个指向常量的指针,也就是不能通过p修改他指向的值
以上我们也可以区分顶层const和底层const(以下描述不仅适用于指针,其他数据类型也可以)
顶层const:指针本身是个常量,指针本身不可变,就是离对象名最近的是const(这种记忆法不一定全对,总之是对象本身的值不改变的就是顶层)
底层const:指针所指的对象是一个常量,也就是所指向的对象不能被改变,离对象名最近的是指针(或其他数据类型)
static
-
static局部变量,因为是static是存在静态区,函数执行结束不会被释放,继续保存在内存,这时的static的作用范围只是这个函数,内存只被分配一次,下次再调用的时候维持原值
-
类中的静态成员变量(或函数)特点属于类不属于对象,当然任何对象都可以共享这个成员变量和函数,我们可以细分成以下几点:
- 静态成员变量,把static加到变量的声明前面,类内声明的静态成员变量的定义必须在任何程序块之外,也就是不被任何花括号包围,必须外部定义,定义的时候带上类名和作用域 A::b ==(类内声明类外定义,定义时不带static,带类名)==调用该变量的时候可以直接类名::变量名,这是static成员变量特有的引用方式,静态成员变量默认初始化为0
- 静态成员变量不会影响类及对象的大小,即sizeof的结果不会被影响,类的大小只与虚函数和变量有关
- 数据共享,静态成员变量属于类不属于某一个对象,因此可以实现数据共享的功能,静态成员在类的所有对象中都是共享的,共享性就是有一个调用静态成员变量的修改了值,其他所有的都会被修改,而且也不会因为对象的创建new或销毁delete而改变,如下代码:
class Test{
public:
static int num;}
int Test::num = 1;//定义在程序块之外
int main(){
Test one;
Test two;
cout << Test::num << " "<< one.num<< " "<< two.num << endl;//打印都是1111
Test::num = 5;
cout << Test::num << " "<< one.num<< " "<< two.num << endl;//打印都是5555}
- 静态成员函数只能访问静态成员变量(这点和const有点像),不能访问非静态成员函数,静态成员函数也是属于类的,也是通过类名::函数名来访问,普通成员函数和变量不能通过类访问,只能通过对象来访问。
- 由于静态成员函数和变量都是属于类,而不是属于对象,所以静态成员函数内部不存在this指针,因为静态成员函数不属于对象,可以用静态成员函数判断类的某些对象是否已经创建,因为他们不能访问类的this指针(this指针一般指当前对象,static不属于任何对象)
- 类内声明了,那么类外定义静态成员函数不需要static关键字,因为static的两个作用就是作用域限制和生存期限制,如果加了关键字,由于作用域的限制,只能在本cpp中,就不能再程序的其他地方调用了,如果其他文件要调用我们一般加extern,但是跟static是对立的,不能用到一起。
- 静态成员函数不能声明为虚函数,只有非静态成员函数才能成为虚函数,因为静态成员函数属于一个类,而不是一个对象,没有this指针,无法对对象进行判别,不属于任何对象
此外: static可以隐藏数据,保护数据,因为static只能在本文件访问,所以在a.cpp声明了static int a,b.cpp就不能访问a,间接实现了保护数据的作用
PS:看到static的这些作用,你是否也想到了单例模式喃