内存模型和名称空间
内容:
1.单独编译
2.存储持续性,作用域和链接性
3.定位new运算符
4.名称空间
单独编译
1.程序的三个部分
头文件:包含结构声明和使用这些结构的函数的原型
源代码文件:包含与结构有关的函数的代码
源代码文件:包含调用与结构相关的函数的代码
2.请不要将函数定义或者变量声明放在头文件里,这样可能会造成重复定义。除非这个函数是内联函数(什么是内联函数请看对象和类的知识点总结)
3.头文件一般包括
函数原型
结构声明
类声明
模板声明
使用#define或const 定义的符号常量
内联函数
个人理解是前四个不会生成声明的变量,而后两个是因为有特殊的链接属性。
4.#linclude<>在计算机标准的头文件里面寻找。
#include<>在源代码目录下寻找,没有的话再去标准的头文件里面寻找。
5.注意:不要将头文件加入到项目列表里,也不要用#include<>里面包含源文件。
6.为了避免重复定义,C++中采用了
#ifndef
...
#endif
来避免重复定义,它不能避免一个文件被重复包含两次,而只是忽略第一次包含之外的所有内容。
7.在链接编译模块时,要确保所有对象文件或库都是由同一个编译器生成的。
存储的持续性,作用域和链接性
数据保留在内存中的时间
1.自动存储持续性:在函数定义中声明的变量(包括函数参数)的存储持续性为自动的。作用域为创建它的代码块,生命周期也是一样。
2.静态存储持续性:在函数定义外定义的变量和使用关键字static定义的变量的存储持续性都为静态。生命周期为主函数存在的时间。
3.线程存储持续性:生命周期为整个线程存在的时间
4.动态粗出持续性:生命周期为程序员掌控,new创建内存,delete释放内存。
可分为
1.代码区:存放函数体二进制代码,有操作系统进行管理
2.全局区:存放全局变量和静态变量和常量。该区域数据在程序结束后由操作系统释放。
3.栈区:由编译器自动释放,存放函数的参数值,局部变量
4.堆区:由程序员分配和释放。
作用域和链接
1.函数的作用域是全局的,不能是局部的。
2.存储方式是通过存储持续性,作用域和链接性来描述的。
3.C++中的auto关键字有指出某个变量为自动存储,例如:
auto float ford;
4.静态持续变量有三种链接性:外部链接性(可在其他文件中访问),内部链接性(只能在当前文件访问),无链接性(只能在当前函数和代码块访问)。
5.
...
int global = 1000;
static int one_file = 50;
int main()
{
....
}
void function(int n)
{
static int count = 0;
int llama;
}
global (外部链接),one_file(内部链接),count(无链接) 都是静态持续但是链接性不同,生命周期都是整个程序运行时存在。所有的静态变量在未初始化前都是默认为0
静态持续性,外部链接性
相当于全局变量。
1.单定义规则要求全局变量(外部变量)是一次定义的,如果要在其他文件当中使用这个全局变量,必须在前面加extern来引用这个变量。
2.在同一个文件下,可以在不同的cpp实现不同的功能,例如在一个cpp文件里面写函数声明,可以在另外一个cpp文件里写函数实现。注意是两个cpp,但是一般不这样做。都是将函数声明写在头文件里面。
3.可以在一个文件里面使用extern表明使用的全局变量。
静态持续性,内部链接性
加限定符static后作用域为整个文件,为内部链接性。
外部链接性的变量可以被其他文件使用,但是内部链接性变量只能被声明它的文件使用。
1.static 关键字表明在这个cpp文件里面一直存在,但是在其他cpp文件里面就不存在,还是可以继续声明相同的变量名。但是没有static关键字就不行。
静态持续性,无链接性
在代码块中声明的变量并且在变量名前加了static关键字,这个属于无链接性,代码块活动时它存在,代码块不活动时它也存在。
个人对这三种静态存储持续性理解:
有外链接性在函数体外声明并且不加static关键字->用于不同的cpp文件之间
有内链接性在函数体外声明并且加有static关键词->用于不同的函数体之间。
无链接性在函数体内部声明并且加有static关键词->用于对同一个函数的多次调用。
说明符和限定符
存储说明符(同一个声明中不能有多个说明符,但是thread_local 除外,它可跟static和extern结合使用)
auto用于自动类型推导
register显示的指出变量是自动的
static 全局声明的时候为内部链接性,在局部声明时表明局部变量是静态存储
extern表明的是引用声明
thread_local在线程中相当于常规静态变量
mutable在用const声明的函数时可以修改被mutable说明的变量。
1.const修饰的全局变量的链接性是内部的
函数和链接性
1.C++不允许在一个函数中定义另一个函数,所以所有的函数的存储持续性都=自动为静态的。
new运算符和定位new运算符
使用new运算符的时候自动在堆区寻找到一个存储空间存储,释放的时候用delete,但是使用定位new运算符的时候必须包含new头文件并且指定存储在哪个空间里面,例如:
#include<new>
char buffer2(500);
....
p4 = new(buffer2)int[20];
## 名称空间
为了避免变量,函数,结构,枚举,类以及类和结构的成员名称的冲突问题。
声明区域:声明区域是可以在其中进行声明的区域
潜在作用域:变量的潜在作用域从声明的区域开始,到其声明区域的结尾。
作用域:变量对程序而言可见的区域。
1.名称空间可以是全局的,可以在另一个名称空间里面声明,但是不能在代码块里面声明。
### using声明和using编译指令
using 声明将特定的名称添加到它所属的声明区域中。
using编译指令使在该名称空间中的全部名称都可以使用。
两者的比较
1.using声明像是在函数里面声明一样,而using编译指令就像是大量的使用::运算符。
2.在使用了using编译指令后,如果在局部函数里面继续声明与所编译的名称空间相同的变量,则会隐藏名称空间的变量,而不会报错,但是使用using声明就会报错。所以使用using声明比使用using编译指令要安全一点。