OOP C++-错误,因为A.h包含B.h,而B.h又包含A.h
OOP C++ - Error as A.h includes B.h which includes A.h again
我正在学习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有共同的需求。
然后我解决了"递归包含问题"
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 编译包含字符串的代码时遇到问题
- c++库的公共头文件中应该包含什么
- 将包含C样式数组的对象初始化为成员变量(C++)
- 是否需要删除包含对象的"pair"?
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 使用mongocxx驱动程序时包含头文件问题
- 如何在h文件中包含.o对象文件
- 在混合代码库中将C转换为C++时出现许多包含错误
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- cmath抛出错误C2062、C2059、C2143和C2447.cmath包含在矢量文件中
- 为什么您需要C++头文件的包含保护
- 无法在UE4中包含BP类到CPP类
- g++ 说函数不存在,即使包含正确的标头
- 在C++代码中包含opencv时,使用ctypes创建.so文件
- Visual C++GC接口如何启用它以及要包含哪个库
- 当调用switch语句中的函数时(即使函数不包含循环),似乎是永不结束的循环的问题
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)