VC++中的头文件包含问题

转载 2012年03月30日 10:58:08


 

在一些大的工程中,可能会包含几十个基础类,免不了之间会互相引用(不满足继承关系,而是组合关系)。也就是需要互相声明。好了,这时候会带来一些混乱。如果处理得不好,会搞得一团糟,根据我的经验,简单谈谈自已的处理办法:

编码时,我们一般会尽量避免include头文件,而是采用声明 class XXX。但有时候还是必须用Include头文件,那么,两者的划分在于什么呢?

应该是很明确的,但书上好像都少有提及。

首先:
我们要明白为什么要用声明取代头文件包含:对了,是为了避免无必要的重编译(在头文件发生变更时)。工程较大,低速机,或基础类经常变更(不合理的设计吧),编译速度还是会在意的,另外,更为重要的是,采用声明可降低代码(class)之间的藕合度,这也是面向对象设计的一大原则。

二:一般原则:
a. 
头文件中尽量少include, 如果可以简单申明 class clsOld; 解决,那最好。减少没有必要的include;
b. 
实现文件中也要尽量少include,不要include没有用到的头文件。

三:那什么时候可以只是简单声明class clsOld呢?
简单的说:不需要知道clsOld的内存布局的用法都可以(静态成员除外),也就是讲如果是指针或引用方式的都行。
比如:
   clsOld * m_pOld;    //
指针占4个字节长
   clsOld & test(clsOld * pOld) {return *pOld};
  
一切OK

四:什么时候不能简单声明class clsOld,必须include呢?
不满足三的情况下:
 
比如:
         clsOld m_Objold;  //
不知道占据大小,必须要通过它的具体声明来计算
原因很简单,想想你要计算sizeof(classNew),但连clsOldsize都不知道,编译器显然会无能为力。

特殊情况:
          int test() { return clsOld::m_sInt;}
    
静态成员调用,想来应该是不需要知道内存布局的,但因为需要知道m_sInt是属于clsOld命名空间的,如果只声明class xxx显然是不足以说明的,所以必须包含头文件。

综上所述,我有以下几点建议:
1
:如果有共同相关依赖(必须include)的类,比如 A,B都依赖可以放在一起,然后直接 Include "d" 类的使用者只需关心与本类暴露出的相关类型,内部用到的类型不用去管(不用自已去include d)。这样给出的class,调用者才更好用(不用去看代码查找,是不是还需要包含其它头文件)

2:如果A类依赖D B类不依赖D,可以把它们分开两个头文件。各自Include。这样可避免当D发生变化时,避免不必要重编译。

3:类中尽量采用指针或引用方式调用其它类,这样就可以只声明class xxx了。并且这也符合资源最优利用,更利于使用多态。


-------------------------------
既然使用了包含文件,为什么还要在class CMainFrame前添加"class CViewerView;"等代码?如果用包含文件代替它,行不行?  很多Visual C++书籍对这些问题避而不谈,但实际上这是一个重要的问题。如果不能理解上述代码,我们很可能为无法通过编译而大伤脑筋。这些问题的出现是基于这样的一些事实:在我们用标准C/C++设计程序时,有一个原则即两个代码文件不能相互包含,而且多次包含还会造成重复定义的错误。为了解决这个难题, Visual C++使用#pragma once来通知编译器在生成时只包含(打开)一次,也就是说,在第一次#include之后,编译器重新生成时不会再对这些包含文件进行包含(打开)和读取,因此我们看到在用向导创建的所有类的头文件中有#pragma once语句就不会觉得奇怪了。然而正是由于这个语句而造成了在第二次#include后编译器无法正确识别所引用的类。因此,我们在相互包含时还需要加入类似class CViewerView这样的语句来通知编译器这个类是一个实际的调用

VC++中的头文件包含问题

在一些大的工程中,可能会包含几十个基础类,免不了之间会互相引用(不满足继承关系,而是组合关系)。也就是需要互相声明。好了,这时候会带来一些混乱。如果处理得不好,会搞得一团糟,根据我的经验,简单谈谈自已...
  • L_Andy
  • L_Andy
  • 2013年09月15日 09:21
  • 1861

vc++常用几个头文件的作用

vc++头文件的解释和应用实例
  • u014260892
  • u014260892
  • 2015年03月17日 09:34
  • 1249

VC++6.0中各种头文件作用

#include //设定插入点   #include //字符处理   #include //定义错误码   #include //浮点数处理   #include //文件输入/...
  • sagittarius_yx
  • sagittarius_yx
  • 2017年01月02日 03:44
  • 548

VC中添加头文件以及库

附加头文件包含 VC6.0中: VC6.0默认include包含路径:Tools>Options>Directories>Include files。 对于特定项目的头文件包含,在“...
  • lwb102063
  • lwb102063
  • 2016年07月29日 20:29
  • 1392

C/C++——头文件重复包含问题

条件编译是解决头文件重复包含的有效方法,在大型程序开发中,往往因类的继承产生重复定义问题,其中一个原因就是头文件的重复包含。有时候虽然重复包含一个头文件不会报错,但同样的代码多次编译也是浪费系统资源,...
  • u010757264
  • u010757264
  • 2015年11月27日 21:47
  • 1364

解决头文件相互包含问题的方法

所谓超前引用是指一个类型在定义之前就被用来定义变量和声明函数。     一般情况下,C/C++要求所有的类型必须在使用前被定义,但是在一些特殊情况下,这种要求无法满足,例如,在类CMyView中保留了...
  • dalleny
  • dalleny
  • 2015年01月22日 11:00
  • 3760

C/C++ 中头文件相互包含引发的问题

C/C++ 中头文件相互包含引发的问题 今天下午遇到一个头文件相互包含而导致的编译问题,花了我不少时间去调试没找到问题,最后晚上跟师兄讨论不少时间,突然有所顿悟! 问题重现 我把问题脱离于项目简...
  • hazir
  • hazir
  • 2014年08月16日 00:39
  • 29010

VC++无法找到头文件或库函数.无法打开包括文件:“iostream”: No such file or directory

在VS下(VS2010,VS2012,VS2013,VS2015),用win32平台下调试时,很多头文件都无法打开,导致程序无法运行,但是在x64平台下,就没有问题。 以前,我就每次都把Win32 平...
  • fouchanglei1876
  • fouchanglei1876
  • 2017年02月12日 14:44
  • 309

C++头文件的重定义问题以及头文件互相包含问题

在C++的头文件里,通常通过 #pragma once与#ifndef两种防止头文件二次编译。   有的人将重复编译,重复包含与重复定义弄混,比如:定义一个类,在实例化它之前并不产生内存开销;这与基本...
  • u010177010
  • u010177010
  • 2016年03月10日 16:04
  • 1068

C++头文件重复包含问题分析及解决方案

一、头文件重复包含问题分析 1) 问题重现 举例说明。假设在某个C++ 头文件 或 源文件 中,包含了A.h和B.h两个头文件: #include "A.h" #include "B.h" ...
  • shufac
  • shufac
  • 2014年04月23日 00:14
  • 1089
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:VC++中的头文件包含问题
举报原因:
原因补充:

(最多只允许输入30个字)