所谓超前引用是指一个类型在定义之前就被用来定义变量和声明函数。
一般情况下,C/C++要求所有的类型必须在使用前被定义,但是在一些特殊情况下,这种要求无法满足,例如,在类CMyView中保留了一个非模式对话框对象指针,该对象用于显示/修改一些信息。为了实现对话框"应用"按钮,把对话框做的修改立刻更新到view界面上,为此,需要在对话框类中需要保存view类的指针,这样定义关系就变成如下的代码:
从编译器角度看,编译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*,这样必然
不会造成超前引用。
说明:本文中,为了叙述方便,把class AClass;语句成为类AClass的声明,把class AClass开始的对AClass的类成员变量、
成员函数原型等的说明称为类的定义,而把在CPP中的部分称为类的定义。如果大家对这三个词有不同的理解,请按照自己的本意
把这三个词换成相应的词来理解。
- 浏览: 84709 次
- 性别:
- 来自: 北京
文章分类
最新评论
发表评论
-
CListCtrl
2009-06-26 16:55 353CListCtrl m_lstParam; // 设置样 ... -
SPin控件增减小数
2009-09-23 16:58 436// 初始化 BOOL CGraphCtrDlg:: ... -
Visual C++中实现双缓冲
2009-09-27 10:00 509双缓冲的原理可以这样形象的理解:把电脑屏幕看作一块黑板。首先 ... -
Const用法小结 [ C/C++ const], 好文章。const值得仔细推敲。对付面试很有用的
2009-10-19 15:59 3481. const常量,如const int ... -
VC判断是否数字和小数
2009-11-21 16:23 314int IsNumIsNumOrDecimal(CString ... -
vector、list、deque区别
2009-12-14 10:04 366vector 表示一段连续的内存区域 每个元素被顺序存储在 ... -
VC++ Ping IP地址
2010-01-08 14:57 864// // Ping.h // ... -
TCHAR,CHAR,LPSTR,LPCSTR,char这几个数据类型有何不同
2010-03-09 12:03 745#ifdef UNICODE typedef ... -
GetBuffer()与ReleaseBuffer()使用
2010-03-10 14:47 537GetBuffer可以获得一个字符数组让你能够方便的对其进行 ... -
CStatic字体设置
2010-03-11 10:56 523CFont font; font.CreateFont(36 ... -
VC三种类型的DLL区别
2010-06-16 14:00 3861、Regular statically linked to ... -
ZeroMemory、memset 和 “={0}”
2011-04-29 13:27 336ZeroMemory 、memset 和 “= ... -
怎样去掉 CPropertySheet 的帮助,应用按钮
2011-07-25 19:03 313怎样去掉 CPropertySheet 的帮助按钮, 今天修 ... -
CMapStringToPtr添加与释放
2011-07-30 09:33 492// 创建MapStringToPtr CMapStrin ... -
标准C++ 与MFC 6.0 中字符串的分割
2011-07-31 13:31 940#include <string> #i ... -
关于char, wchar_t, TCHAR, _T(),L,宏 _T、TEXT,_TEXT、L
2011-08-05 10:34 382char :单字节变量类型,最多表示256 ... -
_tprintf printf printf wprintf _stprintf sprintf sprintf swprintf
2011-08-22 08:52 785TCHAR.H Routine _UNICODE &a ... -
BYTE to CString
2011-08-23 20:06 722BYTE byteArray[100]; // with s ... -
_WIN32_WINNT 0x0500 导致 CFileDialog 异常问题
2012-11-12 21:31 972在开发项目中,回归测试,发现没有改动的模块中的CFileDi ... -
CoInitialize与CoInitializeEx,AfxOleInit()的不同
2012-11-13 14:00 923OleInitialize和CoInitialize的区别 ...
相关推荐
本文说明了,在c++中,当多文件编译时各种头文件及各种类的相互包含时的一些注意事项及解决方法.
C++的头文件互相包含的问题。比较有用的解决办法。
本文中,为了叙述方便,把class AClass;语句成为类AClass的声明,把class AClass开始的对AClass的类成员变量、成员函数原型等的说明称为类的定义,而把在CPP中的部分称为类的定义
如果你的头文件包含了其他头文件,这些头文件的任何改变也将导致那些包含了你的头文件的代码重新编译。因此,我们宁可尽量少包含头文件,尤其是那些包含在其他头文件中的。 使用前置声明可以显著减少需要包含的...
" "二、实验内容和方法 " "(1)实验内容: " "1、编写一个程序algo8-1.cpp,实现不带权图和带权图的邻接矩阵与邻接表的相互转换" "算法、输出邻接矩阵与邻接表的算法,并在此基础上设计一个程序exp8-1.cpp实现如下" ...
这样看来,所有的问题都解决了,是吗? 2 1.4 新的64位机上的64位类型是什么样的? 3 指针声明 3 1.5 这样的声明有什么问题?char *p1, p2; 我在使用p2的时候报错了。 3 1.6 我想声明一个指针,并为它分配...
这样看来,所有的问题都解决了,是吗? 1.4 新的64位机上的64位类型是什么样的? 指针声明 1.5 这样的声明有什么问题?char*p1,p2;我在使用p2的时候报错了。 1.6 我想声明一个指针,并为它分配一些空间,但却...
VC工程的编译原理与过程,将工程中不同的类拆分到不同的原文件中,每一个类由一个.h和.cpp文件共同完成,然后解决头文件重复定义问题,培养了学员良好的编程习惯,也为以后分析MFC Appwizard生成的工程奠定了良好...
这样看来,所有的问题都解决了,是吗? 1.4 新的64位机上的64位类型是什么样的? 指针声明 1.5 这样的声明有什么问题?char *p1, p2; 我在使用p2的时候报错了。 1.6 我想声明一个指针,并为它分配一些空间,但却不行...
实例055 包含网站头文件 86 实例056 包含网站尾文件 87 实例057 包含网站的主文件 88 2.4 条件语句 89 实例058 员工生日提醒 89 实例059 考试成绩评定标准 90 实例060 控制登录用户权限 91 实例061 网页框架的制作 ...
实例055 包含网站头文件 86 实例056 包含网站尾文件 87 实例057 包含网站的主文件 88 2.4 条件语句 89 实例058 员工生日提醒 89 实例059 考试成绩评定标准 90 实例060 控制登录用户权限 91 实例061 网页框架的制作 ...
熟练掌握和巩固C++语言的基本知识和语法规范,深刻体会面向对象的编程思想,掌握使用面向对象程序设计语言C++,学会编写结构清晰、风格良好的C++语言程序,从而具备利用计算机编程分析解决综合性实际问题的初步能力。...
实例112 解决用substr()函数对中文字符串截取时出现乱码的问题 143 实例113 字符串与HTML标记相互转换 144 实例114 运用PHP 5.0新型字符串输出XML数据 145 实例115 判断字符串中是否存在指定子串 146 2.9 正则...
解决以上问题,本文采用索引结构和二级缓存技术实现数据的快速定位,索引结构和二级缓存技术原理如图 3 所示。 图 3 索引结构和二级缓存技术原理图 索引结构采用数组结构实现,根据唯一的变量名,可以定位出内存...
互独立的模块组成,各个模块只负责搜索引擎的一部分功能,相互配合组成完 整的搜索引擎: 搜索引擎的信息源来自于互联网网页,通过“网络爬虫” 将整个“互联网” 的 信息获取到本地,因为互联网页面中有相当大比例...
标准C++中的字符串类取代了C标准C函数库头文件中的字符数组处理函数。 C++中用来做控制态输入输出的iostream类库替代了标准C中的stdio函数库。 C++中的try/catch/throw异常处理机制取代了标准C中的setjmp()和...