c++中头文件互相包含

如果两个类想要相互使用对方,比如A想要有B的指针,而B被点击时要使用A的方法(例如窗口和按钮),想拥有A的指针,就会想到两者互相包含对方的头文件。(注意无论如何都不可能做到诸如A拥有B的实例,而B拥有A的实例,这样的话会出现内存的迭代使得两者占用内存无限大)

第一种方法(错误)

  • A.h
#pragma once
#include "B.h"
class A{
public:
    B* b;
};
  • B.h
#pragma once
#include "A.h"
class B{
public:
    A* a;
};

根据c++编译规则可知这样做是不可行的,因为在编译时假如首先编译A.h,发现它引用B.h,就导入B.h,B.h又包含A.h,如此迭代包含是无法做到编译的(可查看c++编译原理相关资料)

第二种方法(正解)

  • A.h
#pragma once
#include "B.h"
class A{
public:
    B* b;
    void methodA();
};
  • A.cpp
#include "A.h"
void A::methodA()
{
    b->methodB();
}
  • B.h
#pragma once
class A; // 重点,没有包含A.h,只是声明A为一个类型,与之前声明的A没有关系
         // 如果在此.h文件中使用A类型的任何属性方法都会报错
class B{
public:
    A* a;//使用的本文件声明的A类型
    void methodB();
};
  • B.cpp
#include "B.h"
#include "A.h" // 缺失这个包含会报错,此时才是给B.h中声明的A类定义

void B::methodB()
{
    a->methodA();
}

解释

  • 首先需要明确的是c++是以cpp文件为编译单元的,(也就是对每个cpp编译一次),当我们采取第二种方式时,当编译B.cpp这个编译单元是,实际上编译的是
// part1
// B.cpp先include "B.h",以下为B.h中的内容
class A;  
class B{
public:
    A* a; 
    void methodB();
};

// part2
// B.cpp后include "A.h",以下为A.h中的内容
#include "B.h" // 已经导入就不再第二次导入
class A{
public:
    B* b;
    void methodA(); 
};

// part3
// B.cpp include后面的内容
void B::methodB()
{
    a->methodA(); 
}

所以说是
1. part1(B.h)说明了A是一个类名称, 利用了A名称声明B类里面的A* a,
2. part2(B.cpp include A.h) 给出类A的定义(但没有给出方法定义)
3. part3定义B类methodB时使用A.h声明的methodA方法

如果不理解可以阅读 C/C++ 中头文件相互包含引发的问题

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值