头文件相互引用

举报
无敌清风蓝 发表于 2023/11/22 20:20:52 2023/11/22
【摘要】 1.引言这几天在做一个项目,遇到了想保存单例B里面的数据,于是用了一个单例AA类里面定义B的对象,想保存单例B某时的状态,所以头文件里有B.hB类里面的某个成员函数实现需要先实例化A,然后把单例B的状态存在A中的B对象里,所以我在B的头文件里写了A.h这时候编译器就报错了,提示我们不能在A.h中定义B b//A.h​#include"B.h"class A{ //... B b};​//...

1.引言

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

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

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

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

//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文件)中包含相应的头文件。

//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.解决思路二

//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了

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

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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。