第九章 内存模型和名称空间(单独编译)

9.1 单独编译

单独编译就是将组件函数放在独立的文件中,一些共同的声明可以放在头文件中。
头文件常包含内容:

  • 函数原型
  • 使用#define或const定义的符号常量
  • 结构声明
  • 类声明
  • 模版声明
  • 内联函数
    包含头文件时,应使用""而不是<>。如果文件名包括在尖括号中,则C++编译器将在存储标准头文件的主机系统的文件系统中查找;但如果文件名包含在双引号中,则编译器将首先查找当前的工作目录或源代码目录。
    在这里插入图片描述
    定义头文件,使用#ifndef,意味着仅当以前没有使用预处理器编译指令#define定义名称COORDIN_H_时,才处理#ifndef和#endif之间的语句。
    然后等编译器读取之后再定义#define COORDIN_H_
    在这里插入图片描述

9.2 存储持续性、作用域和链接性

在这里插入图片描述
自动存储持续性:函数中声明的变量,在该程序结束后结束
静态存储持续性:静态变量(static关键字声明),整个程序结束后结束
线程存储持续性:关键字thread_local,该线程结束后结束
动态存储持续性:new运算符,一直存在,知道delete释放

9.2.1 作用域和链接

作用域(scope)描述了名称在文件的多大范围内可见。(作用范围(局部或者全局))
链接性(linkage)描述了名称如何在不同单元间共享,链接性为外部的名称可在文件间共享,链接性为内部的名称只能由一个文件中的函数共享,无链接性只能在当前函数或代码块中访问。

9.2.2 自动存储持续性

在默认情况下,在函数中声明的函数参数和变量的存储持续性为自动,作用域为局部,没有链接性。
当局部变量与全局变量同名时(作用域大的和作用域小的同名且作用范围重叠),新的定义会隐藏旧的定义,新定义可见,旧定义暂时不可见,在程序离开该代码块时,原来的定义又重新可见了。
由于自动变量的数目随函数的开始和结束而增减,程序必须在运行时对自动变量进行管理。常用的方法是留出一段内存,并将其视为栈,当函数被调用时,其自动变量将加入到栈中,当程序使用完后,将其从栈中删除。

寄存器变量:关键字register,显式地指出变量是自动的。

9.2.3 静态持续变量

静态变量有固定的内存分配,如果没有显式地初始化静态变量,编译器将把它设置为0。
要想创建链接性为外部的静态持续变量,必须在代码块的外面声明它;要创建链接性为内部的静态持续变量,必须在代码块的外面声明它,并使用static限定符;要创建没有链接性性静态持续变量,必须代码块内声明它,并使用static限定符。(使用范围不同,但是静态变量在整个程序执行期间是一直存在的,其值也是一直存在的

9.2.4 静态持续性、外部链接性

链接性为外部的变量通常简称为外部变量,它们的存储持续性为静态,作用域为整个文件。
单定义规则:变量只能有一次定义。包括定义声明和引用声明。定义声明它给变量分配存储空间,引用声明(关键字extern,不进行初始化)它不给变量分配存储空间(引用已有变量)
如果在多个文件中使用外部变量,需要在一个文件中包含该变量的定义,在使用该变量的其他所有文件中使用extern关键字声明它。

9.2.5 静态持续性、内部链接性

链接性为内部的变量只能在其所属的文件中使用。

9.2.6 静态持续性、无链接性

该变量只在该代码块中可用,但它在该代码块不处于活动状态时仍然存在。

9.2.7 说明符和限定符

说明符:
在这里插入图片描述
mutable:即使结构(或类)变量为const,其某个成员也可以被修改。
限定符:
在这里插入图片描述
volatile:即使程序代码没有对内存单元进行修改,其值也可能发生变化。(可能是共享数据或者硬件因素)
const全局变量的链接性是内部的,如果需要将其改为外部,需要在前面加上extern关键字。

9.2.8 函数和链接性

C++不允许在一个函数中定义另外一个函数,函数在整个程序执行期间都一直存在。在默认情况下,函数的链接性为外部的,可以在文件间共享。加上static可以使函数变为内部的,只在一个文件中使用。

9.2.9 语言链接性

9.2.10 存储方案和动态分配

动态内存有运算符new和delete控制,而不是由作用域和链接性规则控制。因此可以在一个函数中分配动态内存,而在另一个函数中将其释放。
new初始化
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通常,new负责在堆中找到一个满足要求的内存块,new运算符还有另一种变体,被称为定位运算符,它可以指定要使用的位置。要使用定位new运算符,首先需要包含头文件new,然后将new运算符用于提供了所需地址的参数。除了需要指定参数外,句法与常规new运算符相同。

9.3 名称空间

在C++中,名称可以是变量、函数、结构、枚举、类以及类和结构的成员。
声明区域:可以在其中进行声明的区域。(在函数中的变量的声明区域就是所在代码块)
潜在作用域:变量的潜在作用域从声明点开始,到其声明区域结尾。潜在作用域比声明区域小。
每个声明区域都可以声明名称,这些名词独立于在其他声明区域中声明的名称。在一个函数中声明的局部变量不会与在另一个函数中声明的局部变量发生冲突。
C++可以通过定义一种新的声明区域来创建命名的名称空间,一个名称空间中的名称不会与另外一个名称空间的相同名称发生冲突,同时允许程序的其他部分使用该名称空间中声明的东西。
名称空间可以是全局的,也可以位于另外一个名称空间中,但不能位于代码块中。在默认情况下,在名称空间中声明的名称的链接性为外部的。
通过作用域解析运算符::来使用名称空间。
using声明:using 名称空间::变量名。
using编译:using namespace::名称空间。
假设名称空间和声明区域定义来相同的名称。如果试图使用using声明将名称空间的名称导入该声明区域,则这两个名称会发生冲突,从而出错。如果使用using编译指令将该名称空间的名称导入该声明区域,则局部版本将隐藏名称空间版本。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值