所谓超前引用是指一个类型在定义之前就被用来定义变量和声明函数。

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

 1       #ifndef __MYVIEW_H__
 2       #define __MYVIEW_H__
 3       //这是view类的头函数
 4       #include "MyDialog.h"
 5       class CMyView::public CView
 6       {
 7       protected:
 8           CMyDialog * pDlg;
 9           //这里是其他定义
10       };
11       #endif
12     
13       #ifndef __MYDIALOG_H__
14       #define __MYDIALOG_H__
15       //这是对话框类的定义
16       #include "MyView.h"
17       class CMyDialog::public CDialog
18       {
19           protected:
20               CMyView * pView;
21               //其他定义
22       };
23       #endif

从编译器角度看,编译MyDialog.CPP时,系统首先定义宏__MYDIALOG_H__,然后包含MyView.h,MyView.h中的#include "MyDialog.h"由于__MYDIALOG_H__已经定义,所以不再起作用。在CMyView类的声明中,CMyDialog* pDlg ;就会让编译器产生"CMyDialog"类型没有定义之类的错误,编译MyView.CPP文件出现的错误可以类似得到。

更一般的情况,类A和类B需要彼此互相引用,这样必然有一个类会先被定义,而另外一个类后被定义,这样在先被定义的类引用后被定义的类的时候,就导致了所谓的超前引用。

超前引用导致的错误有以下几种处理办法:

1) 使用类声明

在超前引用一个类之前,首先用一个特殊的语句说明该标识符是一个类名,即将被超前引用。其使用方法是:

a)    用class ClassB;声明即将超前引用的类名

b)    定义class ClassA

c)    定义class ClassB;

d)    编制两个类的实现代码。

上述方法适用于所有代码在同一个文件中,一般情况下,ClassA和ClassB分别有自己的头文件和cpp文件,这种方法需要演变成:

a) 分别定义ClassA和ClassB,并在cpp文件中实现之

b) 在两个头文件的开头分别用class ClassB;和class ClassA;声明对方

c) 在两个cpp文件中分别包含另外一个类的头文件

NOTE:这种方法切记不可使用类名来定义变量和函数的变量参数,只可用来定义引用或者指针。

2) 使用全局变量

由于全局变量可以避免超前引用,不用赘述。我的习惯是,把类对象的extern语句加在该类头文件的最后,大家喜欢怎样写那都没有什么大问题,关键是保证不要在头文件中胡乱包含。

3) 使用基类指针。

这种方法是在引用超前引用类的地方一律用基类指针。而一般情况下,两个互相引用的类并不涉及其基类,因此不会造成超前引用。以开始的例子说:在CMyDialog类中用CView*代替CMyView*,在CMyView类中用CDialog*代替CMyDialog*,这样必然不会造成超前引用。

Ref:http://hi.baidu.com/maxlcl/blog/item/523fad180358210535fa41f5.html

转载于:https://www.cnblogs.com/holynn/archive/2010/01/04/1639132.html

头文件相互包含问题的解决办法相关推荐

  1. C++中头文件相互包含的几点问题

    一.类嵌套的疑问 C++头文件重复包含实在是一个令人头痛的问题,前一段时间在做一个简单的数据结构演示程序的时候,不只一次的遇到这种问题.假设我们有两个类A和B,分别定义在各自的有文件A.h和B.h中, ...

  2. c++ 1:非MFC工程使用MFC库时的问题及解决办法(如果要用CString或者提示windows头文件重复包含)...

    非MFC工程使用MFC库时的问题及解决办法(如果要用CString或者提示windows头文件重复包含) vc6和vc71的工程向导中都包含非MFC的工程,诸如win32 console projec ...

  3. 关于cmd中路径包含空格的解决办法

    关于cmd中路径包含空格的解决办法 很多人曾经都纠结于cmd中路径没有空格,昨天看到一篇文章,深受启发 1)最简单的方法就是给路径名上加上"" 然后cd或执行即可: 2)用缩写.比 ...

  4. C语言 define 防止头文件重复包含 - C语言零基础入门教程

    目录 一.头文件重复包含编译器报错 1.简单的理解头文件重复包 2.老流氓的理解头文件重复包 二.通过宏定义解决头文件重复包含 1.通过 #ifndef / #define 解决头文件重复包含 2.通 ...

  5. C/C++ ifndef与头文件重复包含解析

    ifndef 一个预处理指令,作用是判断一个符号是否存在,或者是不存在,与之对应的还有一个ifdef.ifndef一般用于解决头文件重复包含的问题. 符号 符号一般指的是,函数定义的名称,类名,宏名称 ...

  6. VS2012 无法打开文件“kernel32.lib”问题的解决办法

    VS2012 无法打开文件"kernel32.lib"问题的解决办法 参考文章: (1)VS2012 无法打开文件"kernel32.lib"问题的解决办法 ( ...

  7. 头文件的包含以及命名空间的引入尽量写在cpp里

    原文:http://blog.csdn.net/u012234115/article/details/40019945 1,头文件尽量包含在cpp文件里,而不是h文件里 放在.cpp文件中是比较安全的 ...

  8. ubuntu下无法在目录下创建文件夹,权限不足解决办法

    ubuntu下无法在目录下创建文件夹,权限不足解决办法 Ubuntu linux系统下 su:出现: authentication failure的解决办法 ubuntu下 sudo passwd r ...

  9. java ee ide 假死_Eclipse编辑jsp、js文件时卡死现象的解决办法汇总

    使用Eclipse编辑jsp.js文件时,经常出现卡死现象,在网上百度了N次,经过N次优化调整后,卡死现象逐步好转,具体那个方法起到作用,不太好讲.将所有用过的方法罗列如下: 1.取消验证 windo ...

最新文章

  1. JavaScript_下_Dom
  2. 自动驾驶视觉融合-相机校准与激光点云投影
  3. Dialog外部点击事件
  4. linux的gromacs模拟分子运动,分子动力学技术交流---gromacsamber
  5. mac+修改+ssh文件夹权限_用SSH指令批量修改文件夹 文件权限和拥有者
  6. JavaEE笔记(九)
  7. Django从理论到实战(part22)--include模板标签
  8. 9.数据库中的子查询
  9. 我的Go+语言初体验——(7)Go+ 分数型有理数数据类型
  10. Windows7下搭建Eclipse+Python开发环境
  11. 28335scififo中断接收与发送
  12. 如果一个人请优雅的活着。
  13. iOS比较两张图的相似度
  14. Python的学习笔记案例4--52周存钱挑战3.0
  15. 最大报销额(01背包)
  16. linux sd卡启动盘制作工具,Sd卡启动盘的制作(EXT2)
  17. git clone下来的文件中.git文件被隐藏了
  18. Linux之CentOS7.5安装及克隆
  19. 从0基础学习Python(17)[面向对象三大特征[多态]]
  20. 2.Paper小结——《Privacy-preserving blockchain-based federated learning for traffic flow prediction》

热门文章

  1. 销售的基本功(倾听、提问、聊天)
  2. 华为p40为何没有搭载鸿蒙系统?
  3. But don‘t be fooled, this phone does not
  4. Qt——P11 自定义的信号和槽发生重载的解决
  5. SpringBoot多模块项目整合Dubbo
  6. 提高sql性能的方法_三种提高T-SQL性能的方法
  7. 适合初学者的sql_适用于初学者SQL多重连接示例
  8. 在SQL Server中设置最大并行度的不同方法
  9. 再次测试用OLW本地的桌面应用撰写博客园博文
  10. HDU-3374 String Problem (最小表示法)