第九章 内存模型和名称空间
博文地址
记录CCPlus第九章
知识整理
单独编译
c++允许将组件函数放在独立的文件中,可以单独编译这些文件,然后将它们链接成可执行的程序。
如果只修改了一个文件,则可以只重新编译该文件,然后将它与其他文件的编译版本链接。
因此,可以将程序分为三部分:
- 头文件:包含结构声明和使用这些结构的函数的原型
- 源代码文件:包含与结构有关的函数的代码
- 源代码文件:包含调用与结构相关的函数的代码
请不要将函数定义或变量声明放在头文件中,如果在两个文件中包含该文件,则会出现两个函数定义,这将导致错误。
所以,头文件应包含以下内容:
- 函数原型
- 使用
#define
或const
定义的符号常量 - 结构声明
- 类声明
- 模版声明
- 内联函数
同时需要注意引入头文件时双引号与尖括号的区别。
如果文件包含在尖括号中,则c++编译器将在存储标准头文件的主机系统的文件系统中查找
如果文件名包含在双引号中,则编译器首先在当前的工作目录或源代码目录查找。
为了防止头文件被多次定义,需在头文件中添加预处理器编译指令,并且将#define
用于名称,就可以完成该名称的定义
#ifndef NAME_H_
#define NAME_H_
....
#endif
存储连续性,作用域和链接性
c++使用四种不同的方案来存储数据,分别为
- 自动存储连续性:在函数定义中声明
- 静态存储连续性:在函数定义外定义或使用关键字static
- 线程存储连续性:使用关键字thread_local
- 动态存储连续性:使用new和delete创建
作用域描述了名称在文件的多大范围可见,链接性描述了名称如何在不同单元间共享。
自动存储连续性,即在函数中声明的函数参数和变量的存储连续性为自动的,作用域为局部,没有链接性,存储在栈中。就是说只有在定义它们的函数中才能使用它们,当函数结束时,这些变量将消失。
静态存储变量则有3种链接性:
- 外部链接性(可在其他文件中访问):在代码块外面声明
- 内部链接性(只能在当前文件中访问):在代码块外面声明,且使用static限定符
- 无连接性(只能在当前函数或代码块中访问):在代码块内部声明,且使用static限定符
所有静态持续变量在整个程序执行期间都存在,未被初始化的静态变量的所有位都被设置为0
外部变量在遵循单定义规则,即变量只能有一次定义。如果要在多个文件中使用外部变量,只需在一个文件中包含该变量的定义,但在使用该变量的其他所有文件中,都必须使用关键字extern
声明,且不能初始化。
在默认情况下,const
全局变量的链接性是内部的,就像使用了static说明符一样。
动态存储变量使用new与delete关键字。new负责在堆中找到一个足以能够满足要求的内存块。
int *pi = new int (6); //初始化为6、
delete pi;
名称空间
c++标准提供了名称空间工具,以便更好地控制名称的作用域。每个声明区域都可以声明名称,这些名称独立于在其他声明区域中声明的名称。在一个函数中声明的局部变量不会与另一个在函数中声明的局部变量发生冲突。
使用namespace创建名称空间,名称空间是开发的,即可以把名称加入到已有的名称空间。
namespace Jill{
char * goose(const char *);
}
如何访问给定名称空间中的名称?可以通过作用域运算符::,也可以通过using使用名称空间
Jack::pail = 2.34;
using Jill::fetch; //using 声明
using namespace Jill; // using 编译指令
复习题
-
using声明与using编译指令有什么区别?
using声明使名称空间中的单个名称可用,其作用域与using所在的声明区域相同。using编译指令使名称空间所有名称可用。使用using编译指令时,就像在一个包含using声明和名称空间本身的最小声明区域中声明了这些名称。