热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

两个类相互引用的解决方法

1问题提出最近在编写“斗地主”游戏,在程序中有一个“CDealer”类用来实现发牌等等功能,还有一个“CPoker”类,用来表示扑克牌。在CDealer类中包含了一个CPoker类指针的成员变量,而

1 问题提出

最近在编写“斗地主”游戏,在程序中有一个“CDealer”类用来实现发牌等等功能,还有一个“CPoker”类,用来表示扑克牌。在CDealer类中包含了一个CPoker类指针的成员变量,而在CPoker类中也包含了一个CDealer类指针的成员变量,如下所示:

//CPoker类头文件

#pragmaonce

#include"Dealer.h"

class CPoker

{

public:

    CPoker(void);

    ~CPoker(void);

private:

    CDealer *m_pDealer;

};

//CDealer类的头文件

#pragmaonce

#include"Poker.h"

class CDealer

{

public:

    CDealer(void);

    ~CDealer(void);

private:

    CPoker *m_pPoker;

};

程序编译时,错误提示为

poker.h(10) :error C2143: 语法错误: 缺少“;”(在“*”的前面)

poker.h(10) :error C4430: 缺少类型说明符- 假定为int。注意: C++ 不支持默认int

2 问题分析

因为在程序中首先包含的是Dealer.h,所以Dealer.h头文件首先被编译。如图3-1所示。在CDealer类的头文件中,第1步执行了#pragma once之后就进入到第2步,即Poker.h头文件中。在Poker.h头文件中进行第3步,执行#pragma once,之后进入到第4步,也就是Dealer.h中,由于Dealer.h中包含#pragma once,并且此时已经被编译,所以第4步中的#include “Dealer.h”实际上没有执行,继续进行到Poker.h的第5步,定义CDealer类的指针,此时CDealer类实际上还没有定义,因此编译时回报错。

3 问题解决

3.1 类的前向声明

从2中分析可以看到,报错的主要原因是CDealer类没有定义。可以使用类的前向声明(forwarddeclaration)的方式解决这个问题。如

class CDealer;


图3-1 头文件执行流程

在CPoker类定义中映入了类类型CDealer。在类声明之后而定义之前,类CDealer是一个不完全类型(incompetetype),即已知CDealer是一个类,但不知道包含哪些成员,所以使用类的前向定义后,只能声明该类的指针,而不是该类的对象。

同理,在Dealer.h中加入CPoker类的前向声明。

classCPoker;

3.2 将包含头文件的代码放到执行文件

尽量将包含头文件的语句放到执行文件(.cpp文件)中而不是在头文件中(.h文件)。因此,接下来将#include“Poker.h”语句放到Dealer.cpp文件中,而将#include“Dealer.h”语句放到Poker.cpp文件中。

4 小结

对于两个类间相互引用引发的编译错误,可以使用类前向声明的方式解决。类前向声明是一个不完整类型,只能使用其指针。尽量将包含头文件的代码放在cpp执行文件中,而不是h头文件中。


推荐阅读
  • 20100423:Fixes:更新批处理,以兼容WIN7。第一次系统地玩QT,于是诞生了此预备式:【QT版本4.6.0&#x ... [详细]
  • 本文介绍了Linux系统中的文件IO操作,包括文件描述符、基本文件操作函数以及目录操作。详细解释了各个函数的参数和返回值,并提供了代码示例。 ... [详细]
  • 本文深入探讨了HTTP请求和响应对象的使用,详细介绍了如何通过响应对象向客户端发送数据、处理中文乱码问题以及常见的HTTP状态码。此外,还涵盖了文件下载、请求重定向、请求转发等高级功能。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 本文详细介绍了C语言的起源、发展及其标准化过程,涵盖了从早期的BCPL和B语言到现代C语言的演变,并探讨了其在操作系统和跨平台编程中的重要地位。 ... [详细]
  • 异常要理解Java异常处理是如何工作的,需要掌握一下三种异常类型:检查性异常:最具代表性的检查性异常是用户错误或问题引起的异常ÿ ... [详细]
  • 在进行QT交叉编译时,可能会遇到与目标架构不匹配的宏定义问题。例如,当为ARM或MIPS架构编译时,需要确保使用正确的宏(如QT_ARCH_ARM或QT_ARCH_MIPS),而不是默认的QT_ARCH_I386。本文将详细介绍如何正确配置编译环境以避免此类错误。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 本文探讨了在C++中如何有效地清空输入缓冲区,确保程序只处理最近的输入并丢弃多余的输入。我们将介绍一种不阻塞的方法,并提供一个具体的实现方案。 ... [详细]
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • 本文详细介绍了如何在C#程序运行期间防止系统进入休眠模式以及显示器关闭,提供了具体的实现代码示例,并解释了其应用场景。这不仅有助于提高程序的稳定性,还能优化能源管理。适合需要处理长时间任务(如下载或批处理)的开发者参考。 ... [详细]
  • 中科院学位论文排版指南
    随着毕业季的到来,许多即将毕业的学生开始撰写学位论文。本文介绍了使用LaTeX排版学位论文的方法,特别是针对中国科学院大学研究生学位论文撰写规范指导意见的最新要求。LaTeX以其精确的控制和美观的排版效果成为许多学者的首选。 ... [详细]
  • 丽江客栈选择问题
    本文介绍了一道经典的算法题,题目涉及在丽江河边的n家特色客栈中选择住宿方案。两位游客希望住在色调相同的两家客栈,并在晚上选择一家最低消费不超过p元的咖啡店小聚。我们将详细探讨如何计算满足条件的住宿方案总数。 ... [详细]
  • 本题探讨了在大数据结构背景下,如何通过整体二分和CDQ分治等高级算法优化处理复杂的时间序列问题。题目设定包括节点数量、查询次数和权重限制,并详细分析了解决方案中的关键步骤。 ... [详细]
  • 本文详细介绍了JSP的三大指令:page、include和taglib,重点探讨了静态包含与动态包含的区别及其应用场景,并解释了如何使用taglib指令引入第三方标签库。 ... [详细]
author-avatar
兰州老头_337
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有