正确包含基类和子类(派生类)的头文件?

Posted

技术标签:

【中文标题】正确包含基类和子类(派生类)的头文件?【英文标题】:Including header files of base-classes and sub-classes (derived classes) correctly? 【发布时间】:2015-07-28 00:33:45 【问题描述】:

假设我有 2 个基类,Base1 和 Base2。

// Base1.h
#ifndef BASE1_H
#define BASE1_H
#include "Base2.h"

class Base2;

class Base1 
    ...
    void func(Base2* b);
    virtual void subfunc(Base2* b) = 0;
    ...
;
#endif



// Base2.h
#ifndef BASE2_H
#define BASE2_H
#include "Base1.h"

class Base1;

class Base2 
    ...
    void func(Base1 *b);
    virtual void subfunc(Base1* b) = 0;
    ...
;
#endif

并且我在每个头文件中都包含彼此的头文件,因为 Base1 具有以 Base2 作为参数的函数,而 Base2 具有具有Base1 作为参数。

然后假设我有 Base1Base2 的 5 个子类(派生类);

Base1_Sub1、Base1_Sub2、Base1_Sub3、Base1_Sub4、Base1_Sub5 用于 Base1Base2_Sub1、Base2_Sub2、Base2_Sub3、Base2_Sub4、Base2_Sub5 用于 Base2.

我希望能够将 Base1 的 5 个派生类作为类函数的参数,比如说 Base2_Sub1

// Base2_Sub1.h
#ifndef BASE2_SUB1_H
#define BASE2_SUB1_H
#include "Base2.h"
// What else to include!?

class Base2_Sub1 : public Base2 
    ...
    void subfunc(Base1_Sub1 *b);
    void subfunc(Base1_Sub2 *b);
    void subfunc(Base1_Sub3 *b);
    void subfunc(Base1_Sub4 *b);
    void subfunc(Base1_Sub5 *b);
    ...
;
#endif

Base1_Sub1.h 到 Base1_Sub5.h 应该包含在哪个文件中? 我还需要 Base2 的子类(例如 Base2_Sub1)以同样的方式将 Base1 的子类作为函数参数。

我发现正确包含这些标题非常令人困惑,我不知道如何。请帮帮我。

【问题讨论】:

【参考方案1】:

如果您可以通过引入前向声明来避免包含标头,则不需要包含标头。您的Base1.hBase2.h 标头都提供了很好的示例:Base1 只能使用Base2 的前向声明进行编译,因为它只使用指向Base2 的指针; Base2Base1 指针的使用也是如此。因此,可以安全地去除相互包含的内容。

Base1_Sub1.hBase1_Sub5.h 应该包含在哪个文件中?

在它们对应的Base1_Sub1.cppBase1_Sub5.cpp 中是强制性的。其他 cpp 文件应根据需要包含它们。

我还需要Base2 的子类(例如Base2_Sub1)以同样的方式将Base1 的子类作为函数参数。

就包括头文件在内的头文件而言,如果可以使用指向Base1Base2 的指针定义子类的头文件,则根本不要包含头文件。这将缩短编译代码所需的时间。

当然,您需要为您实例化的类以及您调用成员函数或访问其数据成员的类包含标头。

【讨论】:

谢谢各位,在.h中使用前向声明后,必须在.cpp文件中完成包含,我花了2或3个小时来解决它。hamdo ALLAH

以上是关于正确包含基类和子类(派生类)的头文件?的主要内容,如果未能解决你的问题,请参考以下文章

关于C++基类与派生类

C++中派生类的构造函数怎么显式调用基类构造函数?

基类和派生类 小知识点

C#编程,关于基类和派生类

派生类和基类的转换

java中基类和子类的类型是一样的吗?