注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

勇敢的劳尤条

 
 
 

日志

 
 

c++头文件包含注意要点【转】(对我帮助理解很多)  

2013-10-09 17:05:40|  分类: 其他资料 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
C++ 中类的声明和类的定义分开几乎成了一个不成文的规定。这样做的好处是使得类的声明和实现分开,清晰明了,同时便于库函数发布。但是在实际编程中由此也常常 引起了一些由于头文件的包含顺序问题而产生的符号未定义的编译错误,不明白其中原理有时会让人很头疼。要消除符号未定义的错误的编译错误,最基本的一个做 法就是在引用一个符号(包括变量,函数,结构,类等)之前确保它已经声明或者已经定义。

    实际中编码设计过程中,最基本的一个原则就是在类的头文件中最好不要包含其他头文件,因为这样会使类之间的文件包含关系变得复杂化。要最大限度的遵守这个原则,实际编码设计过程可以采用以下两种方法:
 
    方法一是在设计一个类的时候尽量保持类的独立性,即使该类尽可能不要依赖其他类库或者函数库,或者退一步来说,尽量不要在类的声明中依赖其他类。这样,在 该类的声明头文件中就可以没有其他头文件。如果实现中用到了其他的类,那么可以只在该类的实现文件中包含用到的类库或者函数库的头文件就行。
 
    方法二是当类的声明中必须得用到其他类库或者函数库时,方法一便不再适用,当一个类声明中引用的是其他类或结构的指针引用或者是函数引用时,也可以保持上 述原则,做法是采用前向引用,及在该类的声明前面先声明一下该类所用到的类名或者函数名就行。当类声明中引用的是其他类的实例时,上述原则变不能保持,只 有在该类的声明头文件中引用所引用的类库或者函数库的头文件。

然而,实际中,如果一个类要用到很多其他的类指针或者结构指针或者函数名时,虽然采用上述方法二可以保持上述原则,但是在该类的前面将所有用到的类和方法声明一遍会比较麻烦,这种情况下,为了方便也只好在该类的声明头文件中加入其他类库或者函数库中的头文件了。
 
下面举几个例子:
例子1:最简单的一种情况:两个类A和B之间完全没有关系
这种情况下两个类的声明和定义文件中根本不需要包含对方的声明头文件
 
例子2:两个类A和B在实现的时候用到了对方
这种情况只需要在每个类的实现文件文件中包含所用到的类的头文件即可。
 
例子3:两个类A和B在声明的时候通过指针引用到了对方
这种情况下可以在类的声明(头文件中)前面声明一下所用到的类,然后在各自的头文件中包含所用的类的声明头文件。比如:
// A.h
class   B;  
class   A  
{  
B   *pb;  
}
 
// B.h 
class   A;  
class   B  
{  
A   *pa;  
}
 
// A.cpp
#inclue "B.h"
#inclue "A.H"
......
 
// B.cpp
#inclue "A.h"
#inclue "B.h"
......

    还有,在大型工程程序设计中,一个类往往需要用到很多已有的类库及函数库,把一个类所用到的所有类库头文件都加入到类的定义头文件中往往也非常麻烦,这时 的做法是把那些经常用到的头文件加入到一个公共的头文件中,这个公共头文件在比如叫push.h。要注意的是一些头文件也有依赖关 系,这些文件的包含顺序也小心,否则就会出错。ps,头文件的包含顺序应该是从最特殊到一般,比如:我们应该以这样的方式来#include头文件:
从最特殊到最一般,也就是,
#include "本类头文件"
#include "本目录头文件"
#include "自己写的工具头文件"
#include "第三方头文件"
#include "平台相关头文件"
#include "C++库头文件"
#include "C库头文件"

下面有几条很重要的教条,可以参考。

(1) 在头文件中能用类前置声明代替头文件包含的就用前置声明。因为使用类前置声明,当引用的类发生改变时,当前文件不需要重新编译。
           (a)必须要包含头文件的情况
                    (*) A继承C,A类的头文件中必须要包含C的头文件;
                    (*)A中包含C类的成员变量,A类的头文件中必须包含C的头文件;
                    (*)A中的inline函数中引用到了C类的成员,A类的头文件必须包含C的头文件;
           (b)可以用类的前置声明代替头文件的情况
                    (*)A中包含C类的指针成员或引用成员
                    (*)A中声明的函数的参数或返回值是C的变量(C类型,C指针类型,C引用类型);
(2)对于类需要的头文件,尽量在源文件中包含,而在头文件中使用前置声明。在源文件中,只引用需要的头文件,不需要的头文件不引用。
(3)在源文件中包含头文件的顺序遵循如下原则:源文件对应的头文件(类声明)、C标准库、C++标准库、其它库的头文件、你自己工程的头文件。

(4)VS采用了一种预编译头文件机制,对于变动不大的声明,应该放到预编译头文件中。

为了尽量少的在头文件中包含其他头文件,一个类中应该尽量定义其他类的指针或引用数据成员,但是引用数据程序必须在构造函数中赋值,所以最终应该尽量在类中声明其他类的指针数据成员。

使用指针之前是否需要进行空值判断:
在函数中,对应指针参数,如果不希望参数为空时,需要使用arrest来检查参数是否为空。此语句只在Debug版本有效,在正式发布后无效,不影响效率。

在调用带有指针参数的函数时,最好在调用之前检查一下指针是否为空。即遵循谁调用,谁检查的原则。

  评论这张
 
阅读(255)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017