C++内存模型

一、存储持续性函数

C++使用四种不一样方案来存储数据,它们的区别在于数据在内存中保留的时间,也叫作存储持续性spa

(1)自动存储持续性线程

  在函数定义中声明的变量,包括函数参数。翻译

(2)静态存储持续性code

  在函数定义外和使用关键字static定义的变量。它们在程序整个运行过程当中都存在。blog

(3)线程存储持续性内存

  在C++11中,若是使用关键字thread_local声明变量,则变量生命期和所属线程同样长。ci

(4)动态存储持续性作用域

  使用new运算符分配内存的数据。编译器

二、做用域和连接性

做用域描述了名称在文件的多大范围内可见。包括函数定义或者代码块内可见、当前文件内可见和整个程序可见。连接性描述了名称如何在不一样单元间共享。连接性为外部的名称可在文件间共享,连接性为内部的名称只能在当前文件中共享。自动变量的名称没有连接性,由于它们不能共享。做用域和连接性的意思同样。

三、静态存储持续性变量的做用域和连接性

静态存储持续性地变量在程序运行过程当中在内存中都存在,静态变量默认被初始化为0,包括三种做用域和连接性

(1)外部连接性(做用域为整个程序)

在函数或者代码块外面声明的变量,也称为外部变量

(2)内部连接性(做用域为当前文件)

在函数或者代码块外面声明,而且使用static限定符的变量

(3)无连接性(做用域为当前函数或者代码块)

在函数或者代码块内部声明,而且使用static限定符的变量

四、单定义规则

同一个变量,只能有一次定义和初始化。C++提供了两种变量声明,一种为定义声明(defining declaration),简称定义,它为变量分配存储空间;一种为引用声明(referencing declaration),简称声明,它不给变量分配存储空间。引用声明使用关键字extern。外部连接性变量能够在头文件中进行声明,在源文件中进行定义和初始化,其余文件只要引用该头文件便可以访问该变量。内部连接性变量通常在源文件中定义变量,可是在头文件中定义变量也不影响,由于它的做用域为当前文件,若是两个源文件都引用该头文件,那么在两个文件中都将分别定义一个变量,分配两块内存。

五、const外部变量

默认状况下全局变量的连接性为外部的,加上const修饰符后,连接性为内部的。若是但愿const修饰的常量连接性为外部的,则使用extern来修饰,例如extern const int i = 10。和外部变量不一样,外部常量定义和声明必须都加extern修饰符。

六、函数和连接性

函数的存储持续性为静态的,连接性默认为外部的。能够在源文件中定义函数,在头文件中使用extern声明函数,固然extern能够省略。须要在函数定义和声明添加static关键字将函数的连接性变为内部的。非内联函数默认也要知足单定义规则,内联函数不受这一约束。

七、语言的连接性

连接程序要求每一个函数都有不一样的符号名。在C语言中,一个名称只对应一个函数,很容易实现。通常C语言编译器可能将fun这样的函数翻译为_fun。这种方法被称为C语言连接性。C++语言由于重载的使用,一个名称能够对应多个函数。C++编译器须要执行名称矫正或者名称修饰,为重载函数生成不一样的符号名。例如,可能将fun(int)转换为_fun_i,将fun(double,double)转换为_fun_d_d,这种方法被称为C++语言连接性。若是在C++语言中使用C语言编译的库,则由于语言连接性不一样,连接器没法寻找正确的函数符号,须要指定连接器按照C语言连接性去寻找函数符号。例如:

extern "C" void fun(int);

通常若是编译的C库不只供C程序调用,也供C++程序使用,能够在C库头文件中添加以下代码

#ifdef __cplusplus       //若是采用了C++,以下代码使用C编译器
    extern "C" {            //在C语言中添加extern "C"会报错,由于这是C++语言的语法
#endif
/*C语言头文件*/
#ifdef __cplusplus      //结束使用C编译器
    }
#endif   
相关文章
相关标签/搜索