设为首页 加入收藏

TOP

c++中头文件互相包含的方法讲解
2018-01-03 06:06:38 】 浏览:363
Tags:文件 互相 包含 方法 讲解

如果两个类想要相互使用对方,比如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方法

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇在32位与64位系统比较C++主要类型.. 下一篇QML如何通过WebSocket和C++交互?

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目