一:const
C和C++中的区别
1.在C语言中。Const int a=10; 不可以做左值但是 int* p=&a;是正确的 a是常变量
2.在C++中const修饰的是常量,其值不允许改变 int* p=&a;是错误的,C++中编译期将使用该常量的地方替换成了常量的值,普通指针不可指向
3.int arr[a] 在c中 Const int a=10; int arr[a];是错误的,因为编译期间就要确定数组长度,而编译期无法去地址中取值 但是C++中是可以的
4.C++中常量一定要初始化
5.const 修饰的全局变量是一个local符号,而链接时只关心global符号,无法解析的外部符号有两种情况:不存在或者存在但是定义在别的文件中且是一个local符号
6.C++中的常量可能会退化成为常变量,例如 int c=20;const int d=c;//退化为常变量 main中调用fun(10) void fun(const int a)//也会退化为常变量
编译期间也无法确定,都会导致const修饰的常量退化为常变量
7.const修饰的是离他最近的完整类型,修饰的内容是属于它修饰的类型的内容
const修饰指针,如果修饰的内容中没有*则const不参与类型
C++中的特点
8.const修饰的成员变量在初始化列表中初始化
9.常对象只能调用常方法
10.常方法与普通方法可以重载,
11.常方法中this指针是const test* const 普通方法中this指针是test* const
也就是常方法中不可以调用普通方法
12.普通对象可以调用常方法
13.普通方法可以调用常方法
二:static
1.全局静态变量:
在全局数据区内分配内存
如果没有初始化,其默认值为0
该变量在本文件内从定义开始到文件结束可见
2.局部静态变量:
该变量在全局数据区分配内存
如果不显示初始化,那么将被隐式初始化为0
它始终驻留在全局数据区,直到程序运行结束
其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束。
3.static修饰成员变量:不属于对象私有属于对象共享,属于类
修饰成员变量时:
(1)由于不属于对象,即不由构造函数初始话,所以在类外初始化
(2)不依赖对象访问
修饰成员方法时:
(1)无this指针(所以不能访问普通成员变量只能访问静态成员变量),不像类中普通成员方法的this_call的调用约定而是_cdecl的调用约定
(2)无法调用普通成员方法
(3)普通成员方法可以调用静态成员方法 静态成员方法不依赖对象调用
4.static在空类中 对类的大小没有任何影响
1、全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。
2、静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。
3、局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
4、静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
三:引用&
1.是一个变量的别名,底层是一个指针,在使用的地方替换成了指针的解引用(替换时期为编译期,指令生成时)
2.引用必须初始化
3.不允许泄露常量的引用给非常量的引用
4.引用一个不可寻址的常量时,会产生一个临时量
5.标准类型产生的临时量时常量自定义类型产生的是非常量
6.引用单独使用不参与类型 const单独使用也不参与类型 但是const&结合参与类型可以形成重载
7.引用的成员变量一定要在初始化列表中进行初始化
四:inline(在函数调用点会展开)
1.const与define的区别:C++中const可以定义常量,#define也可以定义常量,但是前者比后者有更多优点
(1)const常量有数据类型,而宏常量没有数据类型。编译期可以对const常量进行安全类型检查但是对宏常量只是进行字符替换,没有安全类型检查
(2)可以对const常量进行调试,但是不能对宏常量进行调试。在C++中const常量完全取代宏常量
2.
3.内联函数在编译期间处理,而宏函数在预编译期间处理
4.对于递归函数一定不会用内联处理,因为编译期间无法确定递归的深度
五:virture:多动态 纯虚函数
六:friend:友元函数
七:extern
1.const与static具有相同的一点是,const修饰的全局变量都是local属性,而extren与const连用用来声明该常量可以作用于其他编译模块中
但是 static与extern是平级的,他们两个不可以同时修饰同一个变量
2.函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。
3.extern“C” 只能用在C++文件中,告诉C++编译器,它修饰的函数利用C语言的编译规则进行编译(保持原有函数名)
C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。
4.在一个源文件里定义了一个数组:char a[6];在另外一个文件里用下列语句进行了声明:extern char *a;这种是不可以的,程序运行时会告诉非法访问
原因在于,指向类型T的指针并不等价于类型T的数组。extern char *a声明的是一个指针变量而不是字符数组,因此与实际的定义不同,从而造成运行时非法访问。应该将声明改为extern char a[ ]
八:expilcit:禁止隐式生成临时对象
九:volatile:禁止编译器优化,修饰一个变量时,每次使用该变量都会从内存中重新取出这个值
十:mutable:去除常性