OOP C++-错误,因为A.h包含B.h,而B.h又包含A.h

OOP C++ - Error as A.h includes B.h which includes A.h again

本文关键字:包含 C++- 错误 OOP 因为      更新时间:2023-10-16

我正在学习OOP,对此有疑问。假设我有一个文件ClassA.h,其中包含ClassB.hassB.hlassA.h

这是一个错误,我想我明白为什么会发生这种情况,因为我得到了一个无限的include循环。但在这种情况下该怎么办?有办法解决这个错误吗?还是我应该重新思考我的课程以避免它?这是否意味着我的班级组织设计不好?如果是这样的话,有什么方法可以安排我的"类图"并避免这种情况?

我只是想知道在这种情况下什么是最佳实践。另外,为什么"#pragmaonce"指令不能解决这个问题?提前谢谢。

您也可以通过使用forward声明来解决这个问题。假设您没有创建包含在标头中的类的实际对象,或者没有从中继承,那么如果您只需要在标头中使用它们的指针,就可以这样做。

示例:

ClassA.h
class ClassB;
//rest of the codes here
ClassB.h
class ClassA;
//rest of the codes here
ClassA.cpp
#include ClassA.h
#include ClassB.h
ClassB.cpp
#include ClassB.h
#inlcude ClassA.h

有一种方法可以修复它,但这也意味着你的类组织已经崩溃。

修复它的方法被称为"include-guard",尽管许多编译器也支持#pragma once指令。我想它不起作用,因为#pragma once可能在解析完整个内容之前不会考虑包含头文件。由于递归包含发生在头文件的中间,因此尚未完成解析。

include guard是这样的:

A级:

#pragma once // Just because. It really should help.
#ifndef INCLUDED_CLASSA_H
#define INCLUDED_CLASSA_H
#include "ClassB.h"
//... rest of header file
#endif

在B.h类中:

#pragma once // Just because. It really should help.
#ifndef INCLUDED_CLASSB_H
#define INCLUDED_CLASSB_H
#include "ClassA.h"
//... rest of header file
#endif

组织问题被称为循环依赖,而循环依赖通常是个坏主意。有很多不同的方法可以打破它们,但使用哪种取决于依赖的确切性质和原始原因。

根据问题的不同,您可以使用多种技术之一:

  • 从公共基类继承
  • 将两个类中的一个变成另一个的基类-这是前一个的变体
  • 正向声明-这不是很理想,因为它并没有真正打破循环依赖关系,它只是对其进行了排列,这样你就不需要有一个有问题的循环包含依赖关系
  • 将两个类的某些部分转换为它们都可以使用的类-这是使用组合而非继承的公共基类的另一个变体

还有其他技术。事实上,有一本书有各种各样的技术可以在各种情况下使用,因为消除循环依赖是这本书的一大主题。那本书是约翰·拉科斯的《大规模C++软件设计》。

根据我过去的经验,我使用继承解决了同样的问题。

我解决的方法是。ClassA->ClassB:ClassB由ClassA继承。ClassA和ClassB有共同的需求。

然后我解决了"递归包含问题"