一、为啥?
在C++中,头文件是用来声明函数、类、变量等的地方,通常会包含一些常量、宏定义、类型定义、函数声明等内容。头文件可以被其他源文件或头文件包含,以便在不同的文件中共享声明和定义。
然而,在头文件中引入其他头文件可能会导致一些问题:
1. 增加编译时间:
当一个头文件被多个源文件或其他头文件包含时,每个文件都需要解析和编译这个头文件。如果这个头文件包含了大量的其他头文件,就会导致编译时间增加。
2. 命名冲突:
当多个头文件包含相同的头文件时,可能会导致命名冲突。这是因为头文件中可能包含相同名称的常量、宏定义、类型定义、函数声明等,这些名称可能会被其他头文件或源文件使用,导致编译错误。
3. 难以维护:
如果一个头文件包含了大量的其他头文件,就会使代码变得复杂和难以维护。当需要修改某个头文件时,可能会影响到其他头文件和源文件,从而增加了代码维护的难度。
因此,最好不要在头文件中引入其他头文件,而是在源文件中包含需要的头文件。这样可以减少编译时间、避免命名冲突,也更容易维护代码。当然,在某些情况下,为了方便使用和提高代码复用性,引入其他头文件也是可以接受的,但需要权衡利弊。
二、原则
将需要分配空间的定义放在源文件 例如:
需要分配空间 | 不需要分配空间 |
---|---|
函数的定义 (需要为函数代码分配空间) | 类声明 |
命名空间作用域中变量的定义(需要为变量分配空间) | 外部函数声明 |
外部变量声明 | |
基本数据类型常量的声明 | |
内联函数 |
⚠️⚠️⚠️警告:如果错误分配了空间的定义写入头文件中,在多个源文件包含该头文件时,会导致空间在不同的编译单元中被分配多次,从而在连接时引发错误。
三、如何将变量和函数限制在编译单元内?
命名空间作用域的声明的变量和函数,在默认情况下都可以被其他编译单元访问,但是有时候就是不希望一个源文件中定义多的命名空间作用域的变量和函数被其他源文件引用。这种需求主要是出于两个原因:
①安全考虑,不希望将一个只会在文件内使用的内部变量,或函数暴露给其他编译单元,就像不想暴露私有人员一样。
②防止命名冲突:对于大工程来说,不同文件之中的只在文件内使用的变量名很容易重名,如果将它们暴露出来,在连接时候很容易发生名字冲突。
解决方法:
老方法🎈: 用static
关键字 起到和entern
相反的作用,会使得被static
修饰的变量 和函数无法被其他编译单元引用
新方法🎈: 使用匿名的空间命名
namespace{ //匿名的命名空间
int a;
void fun(int n)
{
n++;
}
}