C++作用域、链接性和存储持续性(上)

发布于 2021-09-18  54 次阅读


作用域scope:

作用域scope: 描述了名称在文件(翻译单元)的多大范围内可见。

C++翻译单元指的是一个.cpp源文件和其包含的所有头文件(直接或间接)的内容的和。

分为以下四种作用域:

  • 命名空间作用域:内部声明的变量、类型、函数对于整个命名空间都可见。
  • 全局作用域:实际上是命名空间作用域的特例,是最外层的命名空间。
  • 类作用域:类内部可见
  • 局部作用域:代码块内部可见

可以使用using关键字指定命名空间实现对不同命名空间内部变量的访问,或者使用域解析操作符"::"指定当前的域。格式为:[域名]::[标识符],当域名为空的时候直接指代的是全局命名空间。

另外还有一种特殊的命名空间,匿名命名空间:

namespace {
... //code
}

此时编译器会自动生成一个唯一的命名空间的名字,并添加上using 语句:

namespace __UNIQUE_NAME__ {
... //code
}

using namespace __UNIQUE_NAME__;

但是你不知道这个自动生成的名字,所以也没有办法在其他地方指定这个命名空间。这个特性通常用于限定某些变量,使其只能在本翻译单元里使用。

链接性linkage

链接性linkage:描述了名称在不同翻译单元间共享

  • 链接为外部的名称可以在其他翻译单元的作用域内使用,命名空间都具有外部链接性
  • 链接性为内部的名称可以在当前翻译单元中的所有作用域使用。
  • 无链接性的名称只能在本作用域使用,不能共享。
  • *语言链接,提供在不同语言之间的名称转换。目前支持的是C和C++,使用extern ”C“ 、extern ”C++"指定
  • *模块链接性,c++20引入模块,名字只能从同一模块单元或同一具名模块中的其他翻译单元的作用域指代。

存储持续性

存储持续性指的是变量在内存中驻留的时期:

  • 自动存储持续性:声明的变量的存储持续性是自动的,在开始执行其函数或代码块时被创建,执行完毕后他们使用的内存被释放。(c++中有两种存储持续性为自动的变量)
  • 静态存储持续性:在函数定义定义的变量和使用关键字static定义的变量,其存储持续性为静态,它们在整个程序运行过程中都存在(c++中有三种存储持续性为静态的变量)
  • 线程存储持续性:当前多核处理器很常见,这些cpu可同时处理多个执行任务。这些程序能够将计算放在可并行处理的不同线程中。如果变量是使用关键字thread_local声明的,则其生命周期与所属的线程一样长。
  • 动态存储持续性:使用new运算符分配的内存将一直存在,直到使用delete运算符将其释放或程序结束为止,这种内存的存储持续性为动态,有时称为自由存储或堆(heap)

代码中,对于某个变量的实例,其拥有自己的存储持续性这个属性。

对于标识符的名称,则拥有对应的链接性和作用域。

我们平时谈到的的变量作用域,实际上是变量名称的作用域。只是其存储持续性和变量的作用域有关系。

C++的声明语法提供了存储类说明符,以及cv限定符,它们与作用域共同决定变量的存储持续性和链接性。

目前在使用的一共有如下存储限定符:

  • <strong>static</strong> - 静态线程存储期和内部链接。
  • <strong>extern</strong> - 静态线程存储期和外部链接。
  • <strong>thread_local</strong> - 线程存储期。
  • <strong>MUTABLE</strong> - 不影响存储期或链接。解释见 const/volatile 。

声明中只可以出现一个存储类说明符,但 THREAD_LOCAL 可以与 STATIC 或 EXTERN 结合 (C++11 起)。


当其他人都认为你要鸽的时候,你鸽了,亦是一种不鸽