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 "":一般表示用户自己定义使用的头文件,编译器 ...
随机推荐
- 基于SMTP协议的CMD命令邮件发送
网上有不少的这类的文章,以是参照这些文章后,自己实际运行的结果.系统使用的是WIN7 旗舰版. 1.打开CMD命令后,连接到SMTP服务器,如连接到QQ的SMTP服务,输入命令 telnet smtp ...
- Objective-c 深浅复制
深浅复制的定义: 浅复制:在复制时,对于被复制对象的每一层都是指针复制. 深复制:在复制时,对于被复制的对象至少有一层是对象复制. 完全复制:在复制时,对于被复制对象的每一层都是完全复制. retai ...
- EasyUI的使用步骤
(1) 将easyui-1.4.3中jquery.min.js\jquery.easyui.min.js复制到工程的script下 (2) 将themes复制到工程中 (3) 在页面中引入2个JS 2 ...
- eclipse设置web项目发布到tomcat根目录下
如果已经将项目绑定到服务器了,那就先删除服务器. 重新添加项目进服务器,双击 修改下面Server Locations到tomcat目录下 顺带可以修改下右上角的超时设置 再点击下方 这样就可以了.
- 基于FPGA的信号消抖
上一篇写了一个按键消抖,按键消抖需要一个计数器.可是有些信号是不需要这么负责的,仅仅是抖动而已.于是我在上一篇博文的基础上做了一点修改,于是有了这个信号消抖的程序 module sig_nojitte ...
- Bootstrap Alert 使用
参考 http://www.bootcss.com/javascript.html#alerts 不过这里没有动态alert的例子 于是再参考http://stackoverflow.com/ques ...
- Spring Boot使用自定义的properties
spring boot使用application.properties默认了很多配置.但需要自己添加一些配置的时候,我们应该怎么做呢. 若继续在application.properties中添加 如: ...
- Microsoft Accelerator for Windows Azure Alum Azuqua 今天启动
云最大的一个优势就是,它使开发人员比以往任何时候都更迅速.更灵活.在 Windows Azure 中开发应用程序时,工程师无需考虑架设服务器.规划容量或进行日常维护.相反,他们可以专注于提出假设 ...
- Android学习笔记(十五)——碎片的生命周期(附源代码)
碎片的生命周期 点击下载源代码 与活动类似.碎片具有自己的生命周期.理解了碎片的生命周期后.我们能够在碎片被销毁时正确地保存事实上例,在碎片被重建时将其还原到前一个状态. 1.使用上一篇的项目Frag ...
- SharePoint 2010以其他用户身份登录的弹出代码
在SharePoint 2010平台中,可以在当前用户登录系统的情况下使用其他用户身份登录,以达到在同一浏览器中切换用户身份的目的. 每个用户登录SharePoint系统之后都会在系统右上角将用户的名 ...