• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 有关C++头文件的包含顺序研究

有关C++头文件的包含顺序研究

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c++顺序表的实现,顺序表c++,c++顺序结构,c++头文件,c++头文件怎么写等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

一.《Google C++ 编程风格指南》里的观点

公司在推行编码规范,领导提议基本上使用《Google C++ 编程风格指南》。

其中《Google C++ 编程风格指南》对于头文件的包含顺序是这样的:
 
Names and Order of Includes
link ▽Use standard order for readability and to avoid hidden dependencies:C library, C++ library, other libraries' .h, your project's .h.
All of a project's header files should belisted as descendants of the project's source directory without use of UNIXdirectory shortcuts . (the current directory) or .. (the parent directory). Forexample, google-awesome-project/src/base/logging.h should be included as
 
#include "base/logging.h"
In dir/foo.cc or dir/foo_test.cc, whosemain purpose is to implement or test the stuff in dir2/foo2.h, order yourincludes as follows:
 
dir2/foo2.h (preferred location — seedetails below).
C system files.
C++ system files.
Other libraries' .h files.
Your project's .h files.
The preferred ordering reduces hiddendependencies. We want every header file to be compilable on its own. Theeasiest way to achieve this is to make sure that every one of them is the first.h file #included in some .cc.
 
dir/foo.cc and dir2/foo2.h are often in thesame directory (e.g. base/basictypes_test.cc and base/basictypes.h), but can bein different directories too.
 
Within each section it is nice to order theincludes alphabetically.
 
For example, the includes ingoogle-awesome-project/src/foo/internal/fooserver.cc might look like this:

<span style="font-size:16px;"> 
#include "foo/public/fooserver.h" // Preferred location. 
 
#include <sys/types.h> 
 
#include <unistd.h> 
 
  
 
#include <hash_map> 
 
#include <vector> 
 
  
 
#include "base/basictypes.h" 
 
#include"base/commandlineflags.h" 
 
#include "foo/public/bar.h" 
 
 </span> 
</div>

在这里我谈一下我对上面的理解(如不当,还请诸位同学指正):

1. 为了加强可读性和避免隐含依赖,应使用下面的顺序:C标准库、C++标准库、其它库的头文件、你自己工程的头文件。不过这里最先包含的是首选的头文件,即例如a.cpp文件中应该优先包含a.h。首选的头文件是为了减少隐藏依赖,同时确保头文件和实现文件是匹配的。具体的例子是:假如你有一个cc文件(Linux平台的cpp文件后缀为cc)是google-awesome-project/src/foo/internal/fooserver.cc,那么它所包含的头文件的顺序如下:

<span style="font-size:16px;">#include "foo/public/fooserver.h" // Preferred location. 
 
#include <sys/types.h> 
#include <unistd.h> 
 
#include <hash_map> 
#include <vector> 
 
#include "base/basictypes.h" 
#include "base/commandlineflags.h" 
#include "foo/public/bar.h" 
 
</span> 
</div>

2. 在包含头文件时应该加上头文件所在工程的文件夹名,即假如你有这样一个工程base,里面有一个logging.h,那么外部包含这个头文件应该这样写:

#include "base/logging.h",而不是#include "logging.h"
 
我们看到的是这里《Google C++ 编程风格指南》倡导的原则背后隐藏的目的是:

1. 为了减少隐藏依赖,同时头文件和其实现文件匹配,应该先包含其首选项(即其对应的头文件)。
 
2. 除了首选项外,遵循的是从一般到特殊的原则。不过我觉得《Google C++ 编程风格指南》的顺序:C标准库、C++标准库、其它库的头文件、你自己工程的头文件中漏了最前面的一项:操作系统级别的头文件,比如上面的例子sys/types.h估计不能归入C标准库,而是Linux操作系统提供的SDK吧。因此我觉得更准确的说法应该是:OS SDK .h , C标准库、C++标准库、其它库的头文件、你自己工程的头文件。
 
3.之所以要将头文件所在的工程目录列出,作用应该是命名空间是一样的,就是为了区分不小心造成的文件重名。
 
二.《C++编程思想》中的不同观点
  
与《Google C++ 编程风格指南》不同的是,《C++编程思想》倡导一种不同的规则。《C++编程思想》P432提到:

头文件被包含的顺序是从“最特殊到最一般”。这就是,在本地目录的任何头文件首先被包含。然后是我们自己的所有“工具”头文件,随后是第三方库头文件,接着是标准C++库头文件和C库头文件。

要了解其原因:可以看JohnLakos在《Large ScaleC++ Softwre Design》(注:其中文译名为《大规模C++程序设计》)中的一段话:
 
保证.h文件的组成部分不被它自身解析(parse),这可以避免潜在的使用错误。因为被自身解析缺乏明确提供的声明或定义。在.c文件的第一行包含.h 文件能确保所有对于构件的物理界面重要的内部信息块都在.h中(如果的确是缺少了某些信息块,一旦编译这个.c文件时就可以发现这个问题)。
 
如果包含头文件的顺序是“从最特殊到最一般”,如果我们的头文件不被它自己解析。我们将马上找到它,防止麻烦事情发生。
 
三.我的试验
 
到底哪一种包含顺序好呢?我使用VS 2005编一个控制台测试工程TestInc,里面有几个文件。
 
MyMath.h的代码如下:

<span style="font-size:16px;">#pragma once 
 
#pragma once 
double acos(double Num); 
</span> 
</div>

MyMath.cpp的代码如下:

<span style="font-size:16px;">double acos(double Num) 
{ 
  return 1.0; 
} 
 
</span> 
</div>

TestInc.cpp的代码如下:

<span style="font-size:16px;">#include "stdafx.h" 
#include "TestInc.h" 
#include <stdio.h> 
#include <math.h> 
 
 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
  double a = acos(0.5); 
  return 0; 
} 
</span> 
</div>

结果出现错误:

1>c:\program files\microsoft visualstudio 8\vc\include\math.h(107) : error C2732: 链接规范与“acos”的早期规范冲突
1>       c:\program files\microsoft visual studio 8\vc\include\math.h(107) : 参见“acos”的声明
 
然后我把TestInc.cpp的头文件包含顺序改为:

<span style="font-size:16px;">#include "stdafx.h" 
#include <stdio.h> 
#include <math.h> 
#include "TestInc.h" 
</span> 
</div>

则编译通过了。在调试运行时main函数调用还是C标准库的函数acos,看来函数调用的顺序是按头文件的包含顺序来的,即我自定义的acos函数被覆盖了(如果TestInc.h里包含了内联函数,则优先调用的是内联函数)。
 
从这个小实验中我得出如下结论:《Google C++ 编程风格指南》和《C++编程思想》倡导的包含头文件的顺序各有优点,《Google C++ 编程风格指南》应该能大量减少隐藏的头文件依赖,而《C++编程思想》则很容易让你清楚知道你所定义的接口是否和系统库及第三方库发生冲突。
 
四.头文件包含中的预编译功能
 
在Visual Studio环境下开发我们发现几乎每个cpp文件都要包含stdafx.h这个文件,而且要把它放在最前面的位置,否则就会出错。这是为什么呢?
      
原来Visual Studio采用一种预编译的机制。要了解预编译机制,先介绍一下预编译头。所谓的预编译头就是把一个工程中的那一部分代码,预先编译好放在一个文件里(通常是以.pch为扩展名的),这个文件就称为预编译头文件这些预先编译好的代码可以是任何的C/C++代码,甚至是inline的函数,但是必须是稳定的,在工程开发的过程中不会被经常改变。如果这些代码被修改,则需要重新编译生成预编译头文件。注意生成预编译头文件是很耗时间的。同时你得注意预编译头文件通常很大,通常有6- 7M大。注意及时清理那些没有用的预编译头文件。
 
也许你会问:现

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 有关C++头文件的包含顺序研究
  • C++实现顺序表的常用操作(插入删出查找输出)
  • C++实现顺序表的方法
  • C++实现翻转单词顺序
  • C++实现顺序排序算法简单示例代码
  • 如何在C++中建立一个顺序表

相关文章

  • 2017-05-28C++输入输出操作符重载的深入分析
  • 2017-05-28浅谈C/C++ 语言中的表达式求值
  • 2017-05-28C语言实现输入一颗二元查找树并将该树转换为它的镜像
  • 2017-05-28简易Dota改键外挂程序制作
  • 2017-05-28基于linux下C开发中的几点技术经验总结
  • 2017-05-28VC中CWinThread类以及和createthread API的区别分析
  • 2017-05-28举例讲解C语言程序中对二叉树数据结构的各种遍历方式
  • 2017-05-28深入分析C++派生类中的保护成员继承
  • 2017-05-28函数指针的强制类型转换实现代码
  • 2017-05-28C语言实现txt数据读入内存/CPU缓存实例详解

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C语言 位域详解及示例代码
    • 关于memcpy和memmove的一点重要说明
    • C语言关键字大全(共32个)
    • C++中Boost库裁剪与其应用详解
    • C++编写简单的打靶游戏
    • 浅析iterator与指针的区别
    • 利用反射获得类的public static/const成员的值实例
    • C++快速幂与大数取模算法示例
    • C++语言数据结构 串的基本操作实例代码
    • 解析为何要关闭数据库连接,可不可以不关闭的问题详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有