VC++中的头文件包含问题
在一些大的工程中,可能会包含几十个基础类,免不了之间会互相引用(不满足继承关系,而是组合关系)。也就是需要互相声明。好了,这时候会带来一些混乱。如果处理得不好,会搞得一团糟,根据我的经验,简单谈谈自已的处理办法:
编码时,我们一般会尽量避免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),但连clsOld的size都不知道,编译器显然会无能为力。
特殊情况:
int test() { return clsOld::m_sInt;}
静态成员调用,想来应该是不需要知道内存布局的,但因为需要知道m_sInt是属于clsOld命名空间的,如果只声明class xxx显然是不足以说明的,所以必须包含头文件。
综上所述,我有以下几点建议:
1:如果有共同相关依赖(必须include)的类,比如 A,B都依赖D 可以放在一起,然后直接 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++中的头文件包含问题的更多相关文章
- VC中添加头文件以及库
原文:http://blog.csdn.net/lwb102063/article/details/52068389 附加头文件包含 VC6.0中: VC6.0默认include包含路径:Tool ...
- vc++中 .H 头文件引用的顺序与符号关系
在使用 #include "math.h" 和 #include <math.h>时,引号 与尖括号的区别如下 此时math.h_1 在工程文件中 math.h_2 ...
- Windows 驱动程序工具包中的头文件
MSDN原文:https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff554695(v=vs.85).aspx Windows 驱动程序 ...
- c++中const变量定义与头文件包含的有关问题
在使用C++进行程序开发的时候,有个常识我们很熟悉,就是把类的定义写在.h文件中,把类的具体实现写在.cpp文件中.这毫无疑问是对的.但我们很少去思考为什么要这样做,本文结合自己的学习体会,对头文件及 ...
- vc下项目的头文件包含目录以及库导入预计库目录设置
1.包含目录:include 头文件包含目录设置: project->setting->C/C++->常规: Additional include directories(附加包含目 ...
- 理解C++中的头文件和源文件的作用【转】
一.C++编译模式通常,在一个C++程序中,只包含两类文件--.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是C+ ...
- VS2008引入头文件包含目录和lib库目录
全局级别的引入 为VS所有项目设置包含目录和库目录,对所有项目都有效 如下图所示:工具-选项-项目和解决方案-VC++目录-包含文件:在此添加头文件目录即可 工具-选项-项目和解决方案-VC++目录- ...
- ZT 头文件包含其实是一想很烦琐的工作 第一个原则应该是,如果可以不包含头文件
当出现访问类的函数或者需要确定类大小的时候,才需要用头文件(使用其类定义) http://blog.csdn.net/clever101/article/details/4751717 看到这个 ...
- C语言中的头文件
1.头文件#include <> :表示引用标准库头文件,编译器会从系统配置的库环境中去寻找 2.头文件#include "":一般表示用户自己定义使用的头文件,编译器 ...
随机推荐
- 练习笔记:net,JqueryUI实现自动补全功能
1.首先建立个空的Web项目 2.将下载好的JqueryUI文件保存到JS文件加下 3.引入JS文件 <link href="JS/css/ui-lightness/jquery-ui ...
- js 触摸事件
js触摸事件 应用在移动端 webkit内核都支持. 触摸事件api https://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html 事件 ...
- unity 播放外部视频
摘要: Unity支持的播放视频格式有.mov..mpg..mpeg..mp4..avi和.asf.只需将对应的视频文件拖拽入Project视图即可,它会自动生成对应的MovieTexture对象. ...
- Java中public,private,final,static等概念的解读
作为刚入门Java的小白,对于public,private,final,static等概念总是搞不清楚,到底都代表着什么,这里做一个简单的梳理,和大家分享,若有错误请指正,谢谢~ 访问权限修饰符 pu ...
- Webform中linq to sql多条件查询(小练习)
多条件查询:逐条判断,从第一个条件开始判断,如果满足,取出放入集合,再从集合中查询第二个条件... aspx代码: <body> <form id="form1" ...
- cocos2d-x 截取屏幕可见区域
在游戏中,我们经常需要分享到社交网络的功能.分享时,我们时常会需要用到截屏的功能.目前网上的文章虽然很多,但是都是截取的 设计分辨率(DesignResolutionSize)大小的屏幕,而这个并不是 ...
- C#指定目录存放DLL
C#开发中,常常会用到不少扩展库,把这些扩展库的大量DLL放在软件目录下面,非常不美观. 通过设置自定义的DLL存放目录,可以把DLL存在指定的目录下面. 代码如下: <?xml version ...
- FOREIGN KEY相关
在添加外键的时候可以在最后通过ON指定行为和三个参数,来表示操作主表数据之后外表的变化 比如若是删除主表之后的变化,就可以 ON DELETE + 三个参数 --删除department表中相关数据行 ...
- python文件操作精髓
总是记不住API.昨晚写的时候用到了这些,但是没记住,于是就索性整理一下吧: python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Pyth ...
- fork出的子进程和父进程的继承关系【转载】
[原文地址]http://blog.163.com/dengjingniurou@126/blog/static/53989196200962924412524/ fork出的子进程和父进程的继承关系 ...