避免头文件的循环依赖关系

对于如何避免头文件的循环依赖关系,你有什么好的build议吗?

当然,从一开始,我尽量devise这个项目是透明的。 但是,随着越来越多的function和类别的添加,项目变得越来越不透明,循环依赖开始发生。

有没有一般的,经过validation的工作规则? 谢谢。

如果你有循环依赖,那么你做错了什么。

例如:

foo.h ----- class foo { public: bar b; }; bar.h ----- class bar { public: foo f; }; 

你可能想要的是非法的:

 foo.h ----- class bar; // forward declaration class foo { ... bar *b; ... }; bar.h ----- class foo; // forward declaration class bar { ... foo *f; ... }; 

这没关系。

一般规则:

  1. 确保每个头可以包含在自己的。
  2. 如果你可以使用前向声明使用它们!
  • 尽可能使用前向声明。
  • 如果只有cpp文件需要,可以将包含头文件的头文件移动到相应的cpp文件中。 最简单的方法是将#include "myclass.h"包含在myclass.cpp
  • 在单独的类之间的交互点处引入接口可以帮助减less依赖性。

一般的方法是将共同性分解成第三个头文件,然后由两个原始头文件引用它们。

另见循环依赖最佳实践

我遵循一些避免循环依赖的最佳实践是,

  1. 坚持OOAD原则。 除非包含的类与当前类有组合关系,否则不要包含头文件。 改用前向声明。
  2. devise抽象类作为两个类的接口。 通过该接口进行类的交互。

取决于您的预处理器function:

 #pragma once 

要么

 #ifndef MY_HEADER_H #define MY_HEADER_H your header file #endif 

如果你觉得devise头文件非常无聊,那么你可能会对 Hwaci(SQLite和化石DVCS的devise者)的头文件感兴趣。

你所瞄准的是一个分层的方法 。 您可以定义模块可以依赖于较低层模块的图层,但是反过来应该由观察者完成。 现在,您仍然可以定义图层的细粒度以及是否接受图层中的循环依赖关系,但是在这种情况下,我会使用它 。

一般情况下,头文件应该向前声明,而不是在可能的情况下包含其他头文件。

同时确保你坚持每个标题一个类。

那么你几乎肯定不会出错。

最糟糕的耦合通常来自臃肿的模板代码。 由于必须在头文件中包含定义,因此通常会导致必须包含所有types的头文件,然后使用该模板的类将包含模板头文件,其中包含其他东西的加载。

出于这个原因,我通常会说:小心模板! 理想情况下,模板不应该在其实现代码中包含任何内容。

虽然Artyom提供了最好的答案,本教程也很棒,并提供了一些扩展http://www.cplusplus.com/forum/articles/10627/