浅析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这样的语句来通知编译器这个类是一个实际的调用

(0)

相关推荐

  • C++常用的#include头文件总结

    本文详细罗列了C++所包含的头文件的名称及作用说明,比较适合初学者了解一下,几乎每一个C++文件的开始都要#include ,可大部分人都没有去关注#include 后面是什么,对照本文的说明相信会对大家理解C++结构多少有些帮助. #include <deque> //STL 双端队列容器 #include <exception> //异常处理类 #include <fstream> //文件输入/输出 #include <functional> //ST

  • C++ 学习之旅二 说一说C++头文件

    一.C++头文件究竟是什么,你怎么看? 每个C++/C程序通常分为两个文件.一个文件用于保存程序的声明(declaration),称为头文件.另一个文件用于保存程序的实现(implementation),称为定义(definition)文件.C++/C程序的头文件以".h"为后缀,C程序的定义文件以".c"为后缀,C++程序的定义文件通常以".cpp"为后缀(像linux等系统以".cc"或".cxx"为后

  • VC++开发中完美解决头文件相互包含问题的方法解析

    所谓超前引用是指一个类型在定义之前就被用来定义变量和声明函数. 一般情况下,C/C++要求所有的类型必须在使用前被定义,但是在一些特殊情况下,这种要求无法满足,例如,在类CMyView中保留了一个非模式对话框对象指针,该对象用于显示/修改一些信息.为了实现对话框"应用"按钮,把对话框做的修改立刻更新到view界面上,为此,需要在对话框类中需要保存view类的指针,这样定义关系就变成如下的代码: 复制代码 代码如下: #ifndef __MYVIEW_H__   #define __MY

  • C++中头文件的概念与基本编写方法

    1 标准库中的头文件 C++标准库中的一切内容都被放在名字空间std中(名字空间中的内容对外是不可见的),但是带来了一个新问题,无数现有的C++代码都依赖于使用了多年的伪标准库中的功能,如声明在<iostream.h>等头文件中的功能,使用std包装标准库导致现有代码的不可用,为了兼容这种情况,标准委员会为包装了std的那部分标准库创建了新的头文件,新的头文件的文件名与旧的一样,只是没有.h这个后缀,如<iostream.h>就变成了<iostream>.对于C头文件,

  • 简单谈谈C++ 头文件系列之(algorithm)

    简介 algorithm头文件是C++的标准算法库,它主要应用在容器上. 因为所有的算法都是通过迭代器进行操作的,所以算法的运算实际上是和具体的数据结构相分离的 ,也就是说,具有低耦合性. 因此,任何数据结构都能使用这套算法库,只要它具有相应的迭代器类型. 算法类别 如上图所示,库中的算法主要分为4类: 非修改性顺序操作(Non-modifying sequence operations) 可变顺序操作(Mutating sequence operations) 排序和关系操作(Sorting

  • 简单谈谈C++ 头文件系列之(bitset)

    简介 该头文件有关位集,实际上是vector 位 位本质上对应bool的概念,只有0或1,true或false两种对立的值. 但很可惜,字节才是机器上最小的存储单元,所以bool基本上是由一个字节大小. bitset是出于高效的空间利用为目的才出现的. 位操作 operator [] : 通过下标访问bit. count : 计数位值为1的位个数. size : 返回位的大小,即有多少个位. test : 测试下标指向的位值是否为1. any : 判断是否有任何一个位值为1. none : 判断

  • C++中头文件和源文件详细介绍

    C++中的头文件和源文件详解 一.C++编译模式 通常,在一个C++程序中,只包含两类文件--.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是C++的源代码. C+ +语言支持"分别编译"(separate compilation).也就是说,一个程序所有的内容,可以分成不同的部分分别放在不同的.cpp文件里..cpp文件里的东西都是相对独立的,在编 译(compile)时不需要与其他文件互通,只需要

  • 浅析VC++中的头文件包含问题

    在一些大的工程中,可能会包含几十个基础类,免不了之间会互相引用(不满足继承关系,而是组合关系).也就是需要互相声明.好了,这时候会带来一些混乱.如果处理得不好,会搞得一团糟,根据我的经验,简单谈谈自已的处理办法: 编码时,我们一般会尽量避免include头文件,而是采用声明 class XXX.但有时候还是必须用Include头文件,那么,两者的划分在于什么呢? 应该是很明确的,但书上好像都少有提及. 首先:我们要明白为什么要用声明取代头文件包含:对了,是为了避免无必要的重编译(在头文件发生变更

  • 浅谈VS中添加头文件时显示无法找到文件的问题

    目录或库文件名中包含汉字或空格的话,请将其用半角双引号括住. 项目.属性.C/C++.附加包含目录:填写附加头文件所在目录 分号间隔多项 项目.属性.链接器.附加库目录:填写附加依赖库所在目录 分号间隔多项 项目.属性.链接器(点前面的+展开).输入.附加依赖项:填写附加依赖库的名字.lib 空格间隔多项 这样在我们添加现有项后,经常出现的找不到源文件等等问题就解决了 以上这篇浅谈VS中添加头文件时显示无法找到文件的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们

  • C++中#include头文件的示例详解

    fstream是C++ STL中对文件操作的合集,包含了常用的所有文件操作.在C++中,所有的文件操作,都是以流(stream)的方式进行的,fstream也就是文件流file stream. 最常用的两种操作为: 1.插入器(<<) 向流输出数据.比如说打开了一个文件流fout,那么调用fout<<"Write to file"<<endl;就表示把字符串"Write to file"写入文件并换行. 2.析取器(>>

  • C/C++语言中的头文件汇总

    stdio.h就是指"standard input&output" 意思就是说标准输入输出头文件! 所以了,用到标准输入输出函数时,就要调用这个头文件 C/C++头文件 include <assert.h> //设定插入点 include <ctype.h> //字符处理 include <errno.h> //定义错误码 include <float.h> //浮点数处理 include <fstream.h> //

  • VScode中C++头文件问题的终极解决方法详析

    目录 引言 局部配置全局配置傻傻分不清楚 一些有帮助的信息 总结 引言 之前在配置VScode环境的时候,按照网上的文章配置,总是找不到头文件,搜索解决方案,都是千篇一律,没有说到重点.在此详细解释一下. 局部配置全局配置傻傻分不清楚 网上很多文章都在讲一个配置文件c_cpp_properties.json,但是有些人不知道什么原因是找不到这个配置文件的.在扩展面板中,点击C++的设置进入的页面其实是通用设置页面,大概长这样: 这里只能看到"在settings.json中编辑"的选项,

  • VScode中添加头文件和源文件(C/C++)的方法

    目录 一.在相同文件夹下 二.在不同文件夹下 总结 一.在相同文件夹下 在正常情况下,若同一文件夹下若头文件.源文件.和主要代码在同一文件夹下,则可以正常运行程序. 如图(此为Visual Studio 示例): 编译结果(无报错): 但在VScode中,同样的使用方式会产生报错. 如下: main.c: #include <stdio.h> #include "myheadfile.h" int main() { myprint("hello"); r

  • 解析VC中预编译头文件的深入分析

    一.为什么预编译头文件:预编译头的概念: 所谓的预编译头就是把一个工程中的那一部分代码,预先编译好放在一个文件里(通常是以.pch为扩展名的),这个文件就称为预编译头文件这些预先编译好的代码可以是任何的C/C++代码,甚至是inline的函数,但是必须是稳定的,在工程开发的过程中不会被经常改变.如果这些代码被修改,则需要重新编译生成预编译头文件.注意生成预编译头文件是很耗时间的.同时你得注意预编译头文件通常很大,通常有6-7M大.注意及时清理那些没有用的预编译头文件.也许你会问:现在的编译器都有

  • 浅谈VC中预编译的头文件放那里的问题分析

    用C++写程序,肯定要用预编译头文件,就是那个stdafx.h.不过我一直以为只要在.cpp文件中包含stdafx.h 就使用了预编译头文件,其实不对.在VC++中,预编译头文件是指放到stdafx.h中的头文件才会有效果.如下: file: stdafx.h 复制代码 代码如下: // stdafx.h : include file for standard system include files,// or project specific include files that are u

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

    一.<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

  • C++中头文件与源文件的作用详解

    一.C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件-- .cpp 文件和 .h 文件.其中,.cpp 文件被称作 C++ 源文件,里面放的都是 C++ 的源代码:而 .h 文件则被称作 C++ 头文件,里面放的也是 C++ 的源代码. C++ 语言支持"分别编译"(separatecompilation).也就是说,一个程序所有的内容,可以分成不同的部分分别放在不同的 .cpp 文件里..cpp 文件里的东西都是相对独立的,在编译(compile)时不需要与其他文件互通

随机推荐