大型项目开发: 头文件顺序
来源:互联网 发布:电脑整蛊软件 编辑:程序博客网 时间:2024/05/18 23:25
经验告诉我们,某些编码实践虽然在C++中完全合法,但是绝对不能应用于大型项目环境中。 大型项目环境下必须有适当的约束,否则很容易变得难以控制并很难维护(摘自<<大规模C++程序设计>>)。下面以Chromium中运用的两个Coding Style中定义的头文件顺序为例。
头文件顺序的差异
WebKit/Blink遵循业界标准的定义,其实也是Lakos在<<大规模C++程序设计>>中建议的顺序 :
- 编译单元对应的头文件 (Related header file)。
- 工程内的其它头文件。
- 库及系统头文件。
(Blink特殊的一点是编译单元必须先包含config.h。)
这样做的目的是为避免隐性依赖。每个头文件都应当做到自包含(Self-Contained, or Self Sufficient), 这样保证用户能直接头文件中理解它的物理依赖。如果遵循这个顺序,当出现隐性依赖时,是无法编译通过的。
下面这个例子:
my_class.h中依赖了std::string, 但没有显式的包含,当main里先包含标准库的头文件string时,编译是不会出错的。
main.cc
#include <string>#include <iostream>#include "my_class.h"int main(int argc, char* argv[]) { MyClass aInstance; std::cout << aInstance.value() << std::endl;}
my_class.h
#ifndef MY_CLASS_H_#define MY_CLASS_H_class MyClass { public: MyClass(); const std::string& value(); private: std::string value_;};#endif
如果遵循上面的规则,就会在编译main.cc时报错:
In file included from main.cc:1:./my_class.h:6:9: error: use of undeclared identifier 'std' const std::string& value();
在一个层次更为清晰的项目下,错误最好归属到作者身上。这里main.cc做为my_class.h的用户,这样的错误最好由my_class.h的作者来解决。所以Google定义了如下的规则:
•关联的头文件
•C库头文件
•C++库头文件
•其它库头文件 * 项目中的其它头文件。
实现如下的my_class.cc时就会收到报错: my_class.cc
#include "my_class.h"#include <string>MyClass::MyClass() :value_("Hello!") {}
在这种情况下,这个错误将只报给my_class.h对应的编译单元my_class.cc。
In file included from my_class.cc:1:./my_class.h:6:9: error: use of undeclared identifier 'std' const std::string& value();
如果是一个小项目,可能察觉不到这样做的差异。但在讲求职责清晰,分工协作的大型项目下,它就会变得很有价值。
这是一个很小的点,可见大型项目中一些规则定义的冰山一角。再比如大型项目中的头文件还有一些设计上的权衡。比如避免不必要包含头文件会拖慢项目的构建效率,引入了前置声明。但它却在一些场景下会造成歧义(比如前置声明标准库中的类,或者模板类),或者引入一些的维护成本和风险(比如函数的参数变化,需要对应修改前置声明)。Google早期是鼓励使用前置声明,而现在只是强调在明确带来好处的情况下才建议使用前置声明。
扩展阅读:
Self-sufficient header files in C/C++
Headers and Includes: Why and How
C/C++ include file order/best practices
2 0
- 大型项目开发: 头文件顺序
- 头文件包含顺序
- DELPHI头文件顺序
- 头文件包含顺序
- 头文件搜索顺序
- 头文件顺序
- c++头文件 引用顺序
- 头文件引用顺序小计
- 头文件包含顺序问题
- 头文件的包含顺序
- 头文件的包含顺序
- include 头文件的顺序
- php开发大型项目小结
- C++大型项目开发约束
- C++大型项目开发约束
- C++大型项目开发约束
- iOS 大型项目开发漫谈
- iOS 大型项目开发漫谈
- android--连连看
- 20150708 MyEclipse Hibernate Setup
- Java学习之-位运算符
- redis相关文章
- Invert Binary Tree
- 大型项目开发: 头文件顺序
- 分割窗口(动态,静态)
- 阿里巴巴产品实习生9天
- LeetCode Number of Islands
- GCD关于队列和函数对于调用线程的影响
- 我的 Xcode 插件单
- CodeForces 228E The Road to Berland is Paved With Good Intentions (2-Sat)
- 【2015_07_09】迷失
- LeetCode228——Summary Ranges