两个不同的类相互引用的情况下头文件包含问题(转)
![此博文包含图片](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
一般情况下,C/C++要求所有的类型必须在使用前被定义,但是在一些特殊情况下,这种要求无法满足,例如,在类CMyView中保留了一个非模式对话框对象指针,该对象用于显示/修改一些信息。为了实现对话框"应用"按钮,把对话框做的修改立刻更新到view界面上,为此,需要在对话框类中需要保存view类的指针,这样定义关系就变成如下的代码:
#ifndef __MYVIEW_H__
#define __MYVIEW_H__
//这是view类的头函数
#include
"MyDialog.h"
class CMyView::
public CView
{
protected:
CMyDialog * pDlg;
//这里是其他定义
};
#endif
#ifndef __MYDIALOG_H__
#define __MYDIALOG_H__
//这是对话框类的定义
#include
"MyView.h"
class CMyDialog::
public CDialog
{
protected:
CMyView * pView;
//其他定义
};
#endif
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/84332c6ec3d72f7bc03bc197c91014ab.png)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客 两个不同的类相互引用的情况下头文件包含问题 - huguotao513 - huguotao513的博客](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
从编译器角度看,编译MyDialog.CPP时,系统首先定义宏__MYDIALOG_H__,然后包含MyView.h,MyView.h中的#include "MyDialog.h"由于__MYDIALOG_H__已经定义,所以不再起作用。在CMyView类的声明中,CMyDialog* pDlg ;就会让编译器产生"CMyDialog"类型没有定义之类的错误,编译MyView.CPP文件出现的错误可以类似得到。
更一般的情况,类A和类B需要彼此互相引用,这样必然有一个类会先被定义,而另外一个类后被定义,这样在先被定义的类引用后被定义的类的时候,就导致了所谓的超前引用。
更一般的情况,类A和类B需要彼此互相引用,这样必然有一个类会先被定义,而另外一个类后被定义,这样在先被定义的类引用后被定义的类的时候,就导致了所谓的超前引用。
超前引用导致的错误有以下几种处理办法:
1) 使用类声明
在超前引用一个类之前,首先用一个特殊的语句说明该标识符是一个类名,即将被超前引用。其使用方法是:
a) 用class B; 声明即将超前引用的类名
b) 定义class A;
c) 定义class B;
d) 编制两个类的实现代码。
上述方法适用于所有代码在同一个文件中,一般情况下,类A和类B分别有自己的头文件和cpp文件,这种
方法需要演变成:
a) 分别定义A和B,并在cpp文件中实现之
b) 在两个头文件的开头分别用class B;和class A;声明对方
c) 在两个cpp文件中分别包含另外一个类的头文件
NOTE:这种方法切记不可使用类名来定义变量和函数的变量参数,只可用来定义引用或者指针。
2) 使用全局变量
由于全局变量可以避免超前引用,不用赘述。我的习惯是尽量少使用全局变量,比较混乱。
1) 使用类声明
在超前引用一个类之前,首先用一个特殊的语句说明该标识符是一个类名,即将被超前引用。其使用方法是:
a) 用class B; 声明即将超前引用的类名
b) 定义class A;
c) 定义class B;
d) 编制两个类的实现代码。
上述方法适用于所有代码在同一个文件中,一般情况下,类A和类B分别有自己的头文件和cpp文件,这种
方法需要演变成:
a) 分别定义A和B,并在cpp文件中实现之
b) 在两个头文件的开头分别用class B;和class A;声明对方
c) 在两个cpp文件中分别包含另外一个类的头文件
NOTE:这种方法切记不可使用类名来定义变量和函数的变量参数,只可用来定义引用或者指针。
2) 使用全局变量
由于全局变量可以避免超前引用,不用赘述。我的习惯是尽量少使用全局变量,比较混乱。
3) 使用基类指针。
这种方法是在引用超前引用类的地方一律用基类指针。而一般情况下,两个互相引用的类并不涉及其基类,因此
这种方法是在引用超前引用类的地方一律用基类指针。而一般情况下,两个互相引用的类并不涉及其基类,因此
不会造成超前引用。以开始的例子说:在CMyDialog类中用CView*代替CMyView*,在CMyView类中用CDialog*代替CMyDialog*,这样必然不会造成超前引用。