一、关键字
1、static
-
全局静态变量
在全局变量前加上关键字static,全局变量就定义成一个全局静态变量.
存储位置:静态存储区,在整个程序运行期间一直存在。
初始化:未经初始化的全局静态变量会被自动初始化为0
作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾。 -
局部静态变量
在局部变量之前加上关键字static,局部变量就成为一个局部静态变量。
存储位置:静态存储区
初始化:未经初始化的静态变量会被自动初始化为0
作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域结束。但是当局部静态变量离开作用域后,并没有销毁,而是仍然驻留在内存当中,只不过我们不能再对它进行访问,直到该函数再次被调用,并且值不变; -
静态成员函数
函数的实现使用static修饰,那么这个函数只可在本cpp内使用,不能被其它cpp使用。 -
类的静态成员变量
在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。对多个对象来说,静态数据成员只存储一处,供所有对象共用。在类外通过 类名::变量名访问静态成员
静态成员变量必须在类中声明,类外定义,定义时不用加static关键字 -
类的静态成员函数
静态成员函数和静态成员变量一样,它们都属于类的静态成员,它们都不是对象成员。因此,对静态成员的引用不需要用对象名。
在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员(这点非常重要)。调用静态成员函数使用如下格式:<类名>::<静态成员函数名>(<参数表>)。
静态成员函数没有this指针,只能访问静态成员,普通成员函数可以访问静态和非静态成员。
2、const
- const修饰的基本数据类型的常量,编译器会把它放到符号表中不分配存储空间,使它成为一个编译期间的值,没有了内存的读写操作,提高了效率 。const修饰的对象则需要分配存储空间,另外对const使用了extern或者&操作符,也会为const常量另外分配空间。
- const修饰形参,一般和引用同时使用,传递效率高,表示参数对象不能被修改。
- 对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const。
- const修饰返回值,返回值不可修改。
- const修饰类数据成员,必须在构造函数的初始化列表中初始化。
- 对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量。
- 非const函数中,this是一个指针常量,指向对象,而const对象中,this是一个指向常量对象的指针常量。
- const成员函数只可以调用const成员。
- 非const成员函数可以调用const成员函数和非const成员函数。
3、extern
- 声明与定义中
C++支持分离式编译,该机制允许将程序分割为若干文件,每个文件单独编译。有些文件中需要共享变量或者函数之类,为了支持这种特性,C++允许将声明与定义分开。一个文件如果想要使用别处定义的名字,必须包含对那个名字的声明。
如果只想要声明,而非定义,在变量名之前添加extern关键字,而非显式地初始化。
extern int i; // 声明i而非定义
int j; //声明并定义
extern int k = 1; //声明并定义
- extern关键字主要修饰变量或者函数,表示函数可以跨文件使用,或者表明变量在其他文件定义,在此处引用。除此之外,extern还可以用来进行链接指定:
当出现extern “C”时,表示 extern “C”之后的代码按照C语言的规则去编译;当extern修饰变量或函数时,表示其具有外部链接属性,即其既可以在本模块中使用也可以在其他模块中使用。
4、volatile
- 不可优化,一种类型修饰符,用它声明的类型变量不能被某些编译器位置因素更改,告诉编译器不对这样的对象进行优化。
- 易变,每次访问必须从内存中取值(没被volatile修饰的变量可能会被编译器优化,从CPU寄存器取值)。
5、explicit
explicit关键字只能用于修饰只有一个参数的构造函数, 它的作用是防止单参数的构造函数隐式类型转换,把一个常量转换成一个对象进行赋值。构造函数默认情况下即声明implicit(隐式),可以把一个常量赋给一个对象。
6、friend
- 友元。使其不受访问权限控制的限制。如在1个类中,私有变量外部是不能直接访问的。可是假如另一个类或函数要访问本类的私有变量时,可以把这个函数或类声明为本类的友元函数或友元类。这样他们就可以直接访问本类的私有变量。
7、inline
- 为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数。
- 当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用。
- 当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联。
8、#define和const的区别
- const 定义的是一个具有常属性的变量,#define定义的只是一个常数没有类型。
- #define定义的常量是在预编译阶段进行替换的,而const定义的具有常属性的变量是在编译期间处理确定其值的。
- const定义的只读变量从汇编角度来看只是给出了对应的内存地址,而不是像#define一样给出的是立即数。
- const定义的只读变量在程序运行期间只有一份拷贝(因为它是全局的只读变量,存放在静态区),而define定义的宏常量在内存中有若干个拷贝。
- const不能重定义,#define可以通过#undef取消某个符号的定义再次进行重新定义。