C++类相互包含

摘要:
注册函数需要气象站类作为正式参数。我需要使用相应类定义的头文件。2.类(和结构)不是相互包容的类。定义时,需要知道类的大小。A和B都不知道实例化对象时要应用多少空间。类在头文件中定义,声明类替换include的定义:在定义类B的头文件中,类B如何调用A.fun()?编译器不知道A中有哪些成员函数。①不要在B类的定义头文件(B.h)中包含其他头文件(A.h)!

1. 两个类需要相互包含的情景

在观察者模式中,气象站的数据送给某些布告牌。

气象站要知道通知哪些布告牌,所以气象站类至少有一个布告牌类型的链表。

布告牌需要把自己注册到气象站类,告诉气象站类自己已经订阅消息,

注册函数需要气象站类作为形参,才知道自己注册到哪一个气象站。

也就是说,在类定义的时候,他们就是需要对方的!

所以,我需要在各自类定义的头文件中,include对方类所在的头文件?错误!

具体错误类型是:语法错误(标识符)。

2.类(和结构体)是不能相互包含的

类在定义的时候需要知道类的大小,实例化的时候才可以正确分配空间。

假如类A正常定义,类B中有类A,这也是OK的,因为类A大小已知,类B大小也就已知了。

假如A中有B,B中有A呢?A和B都不确定大小,好像进入了一个类似死锁的情景。

A和B都不知道自己实例化对象的时候到底申请多少空间。

同样结构体也是一样,是不可以相互包含的!

3. 如何解决需要相互包含的情景?

①尽量使用指针来解决问题

既然是因为大小不确定,导致的类定义错误,那就使用类的指针来替代类好了,使用起来没有什么区别!

在Linux内核中,结构体特别多,肯定会出现相互包含的情况吧,所以Linux内核中尽量采用结构体指针。

以后我们也尽量使用结构体指针,通过pStruct->fun()来调用方法。

②声明类,而不是包含头文件!

类是在头文件中定义的,类在定义的时候需要包含其他类,所以需要在头文件中包含其他头文件。

思考一下头文件相互include,会出现什么情况?

include就是拷贝的意思,互相include,不就是无限制的拷贝下去吗?

所以头文件的相互包含中也不支持。

有什么解决方法呢?声明类取代include定义:class A;

原来不知道,类也是可以声明的!

③如何调用声明类的成员函数?

在定义类B的头文件中,声明了类A,那么类B中如何调用A.fun()?

编译器又不知道A中有哪些成员函数,声明只是告诉有这个类,不提供其他信息。

所以,不要在类的定义头文件中,使用其他类的方法。

在哪里可以使用其他类的方法?在本类的成员函数的实现的cpp文件中可以!

4.总结的几条重要结论!!!

①在类B的定义头文件中(B.h)不要include其他头文件(A.h)!

②在某个类的定义头文件中(B.h)需要其他类(A.h),使用类的声明(class A;)!

③尽量使用类/结构体指针替代对象!

④在某个类的定义头文件中(B.h),不应该调用其他类的方法(A.fun())!

⑤因为要在类B的成员函数的实现c文件中(B.cpp),才会开始调用A的成员函数(A.fun()),

这个时候在B.cpp中包含include “A.h”就不会出问题了!

参考:

c语言结构体相互引用

C++中两个类相互包含引用问题

免责声明:文章转载自《C++类相互包含》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇百度统计部分统计项Multisim 工具之 Spice 仿真下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

统计一个版本代码变化行数

项目总结时,我们常常需要统计代码行数,来查看每个项目开发者的代码总量,提交次数和变更文件数。 这里介绍一下statsvn工具统计代码行数的方法。   1、安装tortoise svn 下载tortoise svn,下载地址:https://tortoisesvn.net/downloads.html,附件给出了64位的版本。 点击运行,按照提示安装完成。...

eclipse svn插件 设置自动加锁相关

 eclipse svn插件 设置自动加锁相关 Subclipse 1.10.9 发布,改进说明:SVNKit 1.8.8Exception proof repository sorter. (1616)Subclipse 是一个为 Eclipse IDE 添加 Subversion 支持的项目。支持几乎所有版本的Eclipse。Eclipse的更新地址是...

VC动态轨迹画线

这是一个绘制直线的简单绘图程序,能过实现动态轨迹画线,在拖动时产生临时线来表示可能画出的直线效果。 首先:建立一个单文档程序,名称为Demo 然后:在视图类的声明文件里面加入数据成员 class CDemoView :public CView{//········protected:         int m_Dragging;     HCURSO...

WSDL2Java操作指南

  1. 安装JDK1.5, 配置系统环境变量:    下载安装JDK后, 设置环境变量:    JAVA_HOME=C:\Program Files\Java\jdk1.5.0_02    Path=%Path%;%JAVA_HOME%\bin(这里的%Path%指你系统已经有的一系列配置)    CLASSPATH=%JAVA_HOME%\lib 2...

docker 和 FastDFS上传和下载文件

1,从仓库拉取镜像 sudo docker image pull delron/fastdfs  也可以解压已经打包好的镜像文件 $ sudo docker load -i 文件路径/fastdfs_docker.tar 2,开启tracker容器   将tracker运行目录映射到宿主机的/var/fdfs/tracker目录中 sudo docker...

LINUX下简单的编译和使用动态链接库[compile .so use c++ in linux]

对动态链接库的概念其实还很模糊,自己的理解是:把一些常用的代码,如函数,类等,编译成一个"包"即DLL(WINDOWS下)或者SO(LINUX下)文件,然后供其它程序使用时直接调用里面封闭的函数即可,实现的代码的重用,也节省了硬盘空间(这点可能是次要的吧).在WIDOWS下利用VC++可方便的生成DLL,在LINUX下则需要通过各种编译命令来实现,对于像我...