避免头文件的循环依赖

发布于 2024-10-14 23:45:52 字数 175 浏览 5 评论 0原文

对于如何避免头文件的循环依赖,您有什么好的建议吗?

当然,从一开始,我就尝试将项目设计得尽可能透明。然而,随着越来越多的功能和类被添加,并且项目变得越来越不透明,循环依赖关系开始发生。

是否有任何通用的、经过验证的、有效的规则?谢谢。

Do you have any good advice on how to avoid circular dependencies of header files, please?

Of course, from the beginning, I try to design the project as transparent as possible. However, as more and more features and classes are added, and the project gets less transparent, circular dependencies start happening.

Are there any general, verified, and working rules? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

梦幻的味道 2024-10-21 23:45:53

取决于您的预处理器功能:

#pragma once

或者

#ifndef MY_HEADER_H
#define MY_HEADER_H
your header file
#endif

如果您发现设计头文件非常无聊,可能是makeheaders您可能会对 Hwaci(SQLite 和化石 DVCS 的设计者)感兴趣。

depending on your preprocessor capabilities:

#pragma once

or

#ifndef MY_HEADER_H
#define MY_HEADER_H
your header file
#endif

If you find it very boring to design header files maybe makeheaders from Hwaci (designers of SQLite and fossil DVCS) could be of interest for you.

神也荒唐 2024-10-21 23:45:53

What you're aiming at is a layered approach. You can define layers where modules can depend on lower layer modules but the inverse should be done with observers. Now you can still define how fine-grained your layers should be and whether you accept circular dependency within layers, but in this case I would use this.

ぽ尐不点ル 2024-10-21 23:45:53

一般来说,头文件应尽可能向前声明而不是包含其他头文件。

还要确保每个标头坚持一个类。

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

最糟糕的耦合通常来自于臃肿的模板代码。因为必须在标头中包含定义,所以通常会导致必须包含各种标头,然后使用模板的类包含模板标头,包括大量其他内容。

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

In general header files should forwardly declare rather than include other headers wherever possible.

Also ensure you stick to one class per header.

Then you almost certainly will not go wrong.

The worst coupling usually comes from bloated template code. Because you have to include the definition inside the header, it often leads to all kinds headers having to be included, and then the class that uses the template includes the template header, including a load of other stuff.

For this reason, I would generally say: be careful with templates! Ideally a template should not have to include anything in its implementation code.

别想她 2024-10-21 23:45:53

尽管 Artyom 提供了最佳答案,但本教程也很棒,并提供了一些扩展 http://www.cplusplus。 com/forum/articles/10627/

Altough Artyom provided best answer this tutorial is also great and provides some extenstions http://www.cplusplus.com/forum/articles/10627/

绝影如岚 2024-10-21 23:45:52

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

例如:

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. 如果您可以使用前向声明,请使用它们!

If you have circular dependency then you doing something wrong.

As for example:

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

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

Is illegal you probably want:

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

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

And this is ok.

General rules:

  1. Make sure each header can be included on its own.
  2. If you can use forward declarations use them!
星星的軌跡 2024-10-21 23:45:52
  • 尽可能使用前向声明。
  • 如果 cpp 文件仅需要任何标头包含,请将其从头文件移出并移至相应的 cpp 文件中。执行此操作的最简单方法是使 #include "myclass.h" 成为 myclass.cpp 中的第一个包含内容。
  • 在不同类之间的交互点引入接口有助于减少依赖性。
  • Use forward declarations where possible.
  • Move any header includes out of a header file and into the corresponding cpp file if they are only needed by the cpp file. Easiest way to enforce this is to make the #include "myclass.h" the first include in myclass.cpp.
  • Introducing interfaces at the point of interaction between separate classes can help reduce dependencies.
花期渐远 2024-10-21 23:45:52

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

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

Some best practices I follow to avoid circular dependencies are,

  1. Stick to OOAD principles. Don't include a header file, unless the class included is in composition relationship with the current class. Use forward declaration instead.
  2. Design abstract classes to act as interfaces for two classes. Make the interaction of the classes through that interface.
迟月 2024-10-21 23:45:52

一般方法是将共性分解到第三个头文件中,然后由两个原始头文件引用。

另请参阅循环依赖最佳实践

A general approach is to factor out the commonalities into a third header file which is then referenced by the two original header files.

See also Circular Dependency Best Practice

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文