前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >头文件相互引用

头文件相互引用

作者头像
无敌清风蓝
发布2024-06-04 19:55:14
1470
发布2024-06-04 19:55:14
举报
文章被收录于专栏:无敌清风蓝

1.引言

这几天在做一个项目,遇到了想保存单例B里面的数据,于是用了一个单例A

A类里面定义B的对象,想保存单例B某时的状态,所以头文件里有B.h

B类里面的某个成员函数实现需要先实例化A,然后把单例B的状态存在A中的B对象里,所以我在B的头文件里写了A.h

这时候编译器就报错了,提示我们不能在A.h中定义B b

代码语言:javascript
复制
//A.h

#include"B.h"
class A
{
  //...
  B b
};

//B.h

#include"A.h"
class B
{
    
};

2.解决思路一

首先这是个循环引用,我想的是编译器先编译的A类,此时B类还没有被编译,所以编译器找不到B的声明,于是就报错了

所以用前向声明来解决这个问题,前向声明允许你在一个类知道另一个类的存在,而不需要知道它的所有细节,也就是在A类前,声明B类,但这种有个问题就是,那类就不能写成对象了B b,而应该用指针或者引用的形式

使用前向声明时,你只能声明指向那个类的指针或引用,因为编译器此时并不知道那个类的大小。如果你需要使用那个类的对象或者调用它的方法,那么你就需要包含那个类的头文件。但是,在头文件中尽量避免包含其他头文件,可以减少编译时间,并且避免可能出现的循环引用问题。如果需要使用其他类的对象或方法,尽量在源文件(.cpp文件)中包含相应的头文件。

代码语言:javascript
复制
//A.h

#include"B.h"
class B;

class A
{
  //...
  B* b
};

//B.h

#include"A.h"
class A;

class B
{
    
};

但是这又不符合我的想法,因为这样的话就用到了指针,而我只不过想让b为一个对象,可以存放B单例的各种数据

百思不得其解的时候,同事给出了这个代码,#include”A.h”不写在B的头文件中,而写在了B的cpp中,这样我发现确实可以,此时B可以定义对象b,也就是解决思路二的代码

3.解决思路二

代码语言:javascript
复制
//A.h

#include"B.h"
class B;

class A
{
  //...
  B b
};

//B.cpp

#include"A.h"

因为头文件的包含(#include)是在预处理阶段完成的,预处理器会把所有的”#include”替换为那个头文件的全部内容。当预处理器在”A.h”中遇到”#include “B.h”“时,它会把”B.h”的内容复制到这里。然后,当预处理器在”B.cpp”中遇到”#include “A.h”“时,它会把”A.h”(此时已经包含了”B.h”的内容)的内容复制到这里。所以,即使”B.cpp”中包含了”A.h”,但是因为这发生在预处理阶段,所以不会产生循环引用的问题。

4.如何保存单例里面的数据呢

本来想用各种拷贝构造,移动构造,发现离开了指针就都G了

代码语言:javascript
复制
/A.h

#include"B.h"
class B;

class A
{
  //...
  B b
};

//B.cpp

#include"A.h"

填坑再写,现在都快0点了

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023/09/14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.引言
  • 2.解决思路一
  • 3.解决思路二
  • 4.如何保存单例里面的数据呢
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档