对于如何避免循环依赖于头文件,您有什么好建议吗?
当然,从一开始,我就尝试将项目设计为尽可能透明。但是,随着越来越多的功能和类的添加,以及项目变得不那么透明,循环依赖开始发生。
是否有任何通用,经过验证且有效的规则?谢谢。
答案 0 :(得分:48)
如果你有循环依赖,那么你做错了。
例如:
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 :(得分:15)
#include "myclass.h"
作为第一个包含在myclass.cpp
中。答案 2 :(得分:7)
我遵循的一些最佳做法是避免循环依赖,
答案 3 :(得分:6)
一般方法是将共性分解为第三个头文件,然后由两个原始头文件引用。
答案 4 :(得分:4)
取决于您的预处理器功能:
#pragma once
或
#ifndef MY_HEADER_H
#define MY_HEADER_H
your header file
#endif
如果您觉得设计头文件非常无聊,可能会感兴趣的是来自Hwaci(SQLite和化石DVCS的设计者)的makeheaders。
答案 5 :(得分:3)
您的目标是 layered approach 。您可以定义模块可以依赖于较低层模块的层,但反之则应该使用 observers 。现在,您仍然可以定义图层的细粒度以及是否接受图层内的循环依赖,但在这种情况下,我会使用this。
答案 6 :(得分:3)
通常,头文件应该向前声明,而不是尽可能包含其他头文件。
同时确保每个标题都坚持一个班级。
然后你几乎肯定不会出错。
最差的耦合通常来自膨胀的模板代码。因为你必须在标题中包含定义,它通常会导致必须包含所有类型的标题,然后使用模板的类包括模板标题,包括其他东西的加载。
出于这个原因,我一般会说:小心模板!理想情况下,模板不应在其实现代码中包含任何内容。
答案 7 :(得分:2)
尽管Artyom提供了最佳答案,但本教程也很棒,并提供了一些扩展{{3p>