我们在编译模块中的任意一个文件中书写的变量/函数在此模块中其他文件中都可以被访问到,但是其他编译模块的文件是没有访问此变量的权限的。那么如何跨模块共享变量 / 函数呢?
答案就是使用 extern. 在这里请在做的各位牢牢记住它的定义:标示所修饰的变量或函数的可能位于其他模块。
一定要牢牢记住上面的定义, 带着定义我们就可以想明白以下问题:
implementation file 中使用一个外部变量要先 extern 声明该变量 (或者导入该变量所在的 header file)?header file 中要使用 extern 声明一个变量?这样当我们编译某个单元时, 编译器发现了使用 extern 修饰的变量,
ld: symbol(s) not found for architecture x86_64;test1.h 中声明 extern int a;test1.cpp 中定义 int a = 10; (或者使用 int a; 定义, 这样的话值是默认值 0)test2.cpp 中 #include "test1.h", 这样便可以在 test2.cpp 中直接使用 a 变量了.在头文件 test1.h 中直接 extern int a = 10;
这样属于在头文件中直接定义, 我们已经说了 一个变量可以被多处声明, 但只能定义在一处, 在这种情况下如果有多个 implementation file 都 #include "test1.h", 那么会造成在 obj 文件的 链接 阶段发现多处存在同一个变量的定义, 这时会报错 ld: 1 duplicate symbol for architecture x86_64
在头文件中定义一个变量属于非常业余的做法, 请不要争相模仿
在头文件 test1.h 中 直接 extern int a = 10; 在 test2.cpp 中直接使用 extern int a;(没有 #include test1.h)
这样做可以避免多处重复定义的问题, 但是这样的话 test1.h 定义的其他变量与方法都不可以使用了, 必须全部使用 extern *** 的形式进行声明然后使用, 这样会及其得不偿失.
所以我们可以得出结论:只在头文件中做声明!!!
真理总是这么简单!
函数与变量类似, 也分为定义与声明. 但是与变量在声明时必须要包含 extern 不同, 由于函数的定义和声明是有区别的:
所以函数定义和声明时都可以将 extern 省略掉, 反正其他文件也是知道这个函数是在其他地方定义的, 所以不加 extern 也行.
所以在 cpp 中, 如果在一个函数前添加了 extern, 那么仅表示此函数可能在别的模块中定义; 或者也可以让我们在只使用了某个头文件的这个方法时不用
#include <***.h>
static使用当 static 用于修饰类中的变量/函数,表明该变量/函数是一个静态成员变量/函数:
当 static 用于修饰类之外的变量/函数,表明该变量/函数是一个普通的全局静态成员变量/函数:
extern 声明也不可以), 不是真正意义的全局(普通的函数默认是 extern 的)static, 比如函数中要返回一个数组, 不想让这个数组函数结束时被释放, 那么可以使用 static 修饰此局部变量static 使变量只在本编译模块内部可见, 这样的话如果两个编译模块各自都有一个 value变量的话, 那么千万不要将两个编译模块内 static 修饰的变量认为是同一份内存, 他们实际上是两份内存, 修改其中一个不会影响另外一个
当 const 单独使用时它就与 static 相同, 而当与 extern 一起合作的时候, 它的特性就跟 extern 的一样了。
#ifndef 能保证你的头文件在本编译模块只被编译一次(但是多个模块都编译此段代码的话则还是会有重复代码)
一般格式:
- #ifndef <标识>
- #define <标识>
- ...
- ...
- #endif
使得编译器可以根据这个名字是否被定义,再决定要不要继续编译该头文中后续的内容。
<标识> 在理论上来说可以是自由命名的,但每个头文件的这个<标识>都应该是唯一的。标识的命名规则一般是:
这个方法虽然简单,但是写头文件时一定记得写进去。
头文件 & 声明 & 定义 的规则header file 中是对于该模块接口的声明, 接口包括该模块提供给其它模块调用的外部函数及外部全局变量, 对这些变量和函数都需在 header file 中冠以 extern 关键字声明implementation file 开头冠以 static 关键字声明header file 中定义变量#include 其 header file 即可.❝如果工程很大, 头文件很多, 而有几个头文件又是经常要用的, 那么
header file 里面去, 比如写到 preh.hpreh.cpp, 里面只一句话: #include "preh.h"preh.c, 在 project setting 里面设置 create precompiled headers, 对于其他 c++ 文件, 设置 use precompiled header file