OOP C ++ - 错误,因为A.h包括B.h,其中包括A.h

时间:2013-02-15 01:28:34

标签: c++ oop header include

我正在学习OOP并且有疑问。假设我有一个包含 ClassB.h 的文件 ClassA.h ,并且在某些时候我的 ClassB.h 需要包含 ClassA .H 即可。

这会导致错误,我想我明白为什么会发生这种情况,因为我得到了一个无限的包含循环。但在这种情况下该怎么办?有没有办法解决这个错误?或者我应该重新考虑我的课程以避免它?这是否意味着我的班级组织设计不佳?如果是这样,那么安排我的“类图”并避免这种情况的方法是什么?

我只是想知道在这种情况下最佳做法是什么。另外,为什么“#pragma once”指令不能解决这个问题呢?提前谢谢。

3 个答案:

答案 0 :(得分:4)

有一种方法可以修复它,但这也意味着您的班级组织已经破裂。

修复它的方法称为“包含保护”,但许多编译器也支持#pragma once指令。我认为它不起作用,因为#pragma once可能不会考虑包含头文件,直到整个事情被解析。由于递归包含发生在头文件的中间,因此尚未完成解析。

包含守卫是这样的:

在ClassA.h中:

#pragma once // Just because. It really should help.
#ifndef INCLUDED_CLASSA_H
#define INCLUDED_CLASSA_H

#include "ClassB.h"

//... rest of header file

#endif

在ClassB.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

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

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

  • 从公共基类继承
  • 将其中一个类转换为另一个的基类 - 这是前一个类的变体。
  • 前向声明 - 这不是那么理想,因为它并没有真正打破循环依赖,它只是安排它,所以你不需要也有一个有问题的循环包含依赖。
  • 将两个类的一部分转换为可以使用的类 - 这是使用组合而不是继承的公共基类的另一种变体。

还有其他技巧。事实上,有一本书在各种情况下都有各种各样的技术,因为删除循环依赖是本书的一个重要主题。那本书是"Large-Scale C++ Software Design" by John Lakos

答案 1 :(得分:4)

你也可以通过使用前向声明解决这个问题。如果您没有创建要包含在标题中的类的实际对象,或者不继承它,那么如果您只需要在标题中指定它们,则可以执行此操作。

示例:

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

答案 2 :(得分:-1)

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

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

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