第九章——内存模型和名称空间

单独编译 

C++允许程序员将组件函数放在独立的文件中。下面列出了头文件中常包含的内容:

  • 函数原型
  • 使用#define或const定义的符号常量
  • 结构声明
  • 类声明
  • 模板声明
  • 内联函数

将结构声明放在头文件中是可以的,因为它们不创建变量,而只是在源代码文件中声明结构变量时,告诉编译器如何创建该结构变量;同样模板声明不是将被编译的代码,它们指示编译器如何生成与源代码中的函数调用相匹配的函数定义

对于头文件,如果是标准头文件,就要用尖括号包含,C++编译器将在存储标准头文件的主机系统的文件系统中查询 ;如果是自己写的头文件,就要包含在双引号中,编译器首先查找当前的工作目录或源代码目录,如果没有找到,才会在标准位置查找。

头文件管理

在同一个文件中只能将同一个头文件包含一次。但是可能在不知情的情况下将头文件包含多次,例如可能使用了包含另外一个头文件的头文件。有一种标准的C/C++技术可以避免多次包含同一个头文件。它是基于预处理器编译指令#define的(现假设有一个头文件COORDIN_H)

#ifndef COORDIN_H
#define COORDIN_H

//place include file contents here

#endif

 上面的语句意味着仅当以前没有使用预处理器编译指令#define COORDIN_H时,才处理#ifndef和#endif之间的语句

编译器首次遇到该文件时,名称COORDIN_H没有定义,这时编译器将查看#ifndef和#endif之间的内容(正是我们希望的),并读取定义COORDIN_H的一行。如果在同一个文件中遇到其他包含coordin.h的代码,编译器将知道COORDIN_H已经被定义了,从而跳到#endif后面的一行。(注意:这种方法并不能防止编译器将文件包含两次,而只是让它忽略除第一次包含之外的所有内容)

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

 存储类别 如何影响信息在文件中的共享

  • 自动存储持续性:在函数定义中声名的变量(包括函数参数)的存储持续性为自动的。它们在程序开始执行其所属的函数或代码块时被创建,在执行完函数或代码块时,它们使用的内存被释放
  • 静态存储持续性:在函数定义外定义的变量和使用关键字ststic定义的变量的存储性都为静态。它们在程序整个运行过程中都存在
  • 线程存储持续性:当前多核处理器很常见,这些CPU可同时处理多个执行任务,这让程序能够将计算放在可并行处理的不同线程中。
  • 动态存储持续性:用new运算符分配的内存将一直存在,直到使用delete运算符将其释放或程序结束为止。这种内存的存储持续性为动态,有时被称为自由存储(free store)或堆(heap)

作用域和链接 

作用域描述了名称在文件的多大范围内可见。(例如,函数中定义的变量可在该函数中使用,但不能在其他函数中使用;而在文件中的函数定义之前的变量则可在所有函数中使用)。链接性描述了名称如何在不同单元间共享

C++变量的作用域有多种。作用域为局部的变量只在定义它的代码块中可用。代码块是由花括号括起来的一系列语句。作用域为全局的变量在定义位置到文件末尾之间都可以使用

自动存储持续性

 默认情况下,在函数中声明的函数参数和变量的存储持续性为自动,作用域为局部,没有链接性。也就是说如果在代码块中定义了变量,则该变量的存在时间和作用域将被限制在该代码块内

 

 静态持续变量

C++为静态持续变量提供了3种链接性:外部链接性(可在其他文件中访问)、内部链接性(只能在当前文件中访问)和无链接性(只能在当前函数或代码块中访问)

要想创建链接性为外部的静态持续变量,必须在代码块的外面声明它;要想创建链接性为内部的静态持续变量,必须在代码块的外面声明它,并使用static限定符;要创建没有链接性的静态持续变量,必须在代码块内声明它,并使用static限定符

int global = 1000;            //static duration, external linkage
static int one_file = 50;     //static duration, internal linkage
int main()
{
...
}

void funct1(int n)
{
    static int count = 0;     //static duration, no linkage
    int llama = 0;
}

void funct2(int q)
{
...
}

所有静态持续变量(上例中的global、one_file、count)在整个程序执行期间都存在

在funct1()中声名的变量的count的作用域为局部,没有链接性,这意味着只能在funct1()函数中使用它,就像自动变量llama一样。但是与llama不同的是,即使在funct1()函数没有被执行时,count也留在内存中。

global和one_file的作用域都为整个文件,即在从声明位置到文件结尾的范围内都可以被使用。具体来说就是可以在main()、funct1()和funct2()中使用它们。由于one_file的链接性为内部,因此只能在包含上述代码的文件中使用它;而global的链接性为外部,因此可以在程序的其他文件中使用它

所有的静态持续变量都有如下初始化特征:未被初始化的静态变量的所有位都被设置为0.这种变量被称为零初始化的。

名称空间

在C++中,名称可以是变量、函数、结构、枚举、类以及类和结构的成员

传统的C++名称空间

声明区域。声明区域是可以在其中进行声明的区域。例如可以在函数外面声明全局变量,对于这种变量其声明区域为其声明所在的文件

潜在作用域。变量的潜在作用域从声明点开始,到其声明区域的结尾。因此潜在作用域比声明区域小,这是由于变量必须定义后才能使用。(然而,变量并非在其潜在作用域内的任何位置都是可见的,例如它可能被另一个在嵌套声明区域中声明的同名变量隐蔽。

 

 新的名称空间特性

C++新增了这样一种功能,即通过定义一种新的声明区域来创建命名的名称空间,这样提供了一个声明名称的区域。一个名称空间中的名称不会与另一个名称空间中的相同名称发生冲突,同时允许程序的其他部分使用该名称空间中声名的东西。下面使用新的关键字namespace 创建两个名称空间:T1和T2

namespace T1{
    double pail;
    void fetch();
    int pal;
    struct Well{...};
}

namespace T2{
    double bucket(double n);
    double fetch;
    int pal;
    struct Hill{...};
}

猜你喜欢

转载自blog.csdn.net/yangSHU21/article/details/131651692