前向声明包括,声明顶部包括(ClassFwd.h + Class.h)

发布于 2024-09-27 15:22:54 字数 600 浏览 9 评论 0原文

在《Effective C++》(第 3 版)中,Scott Meyers 在第 31 条中建议,类应该在其经典声明 (.h) 和定义 (.cpp) 文件之上有一个前向声明包含文件 (fwd.h),可以使用不需要完整定义的类,而不是向前声明自己。

我在某种程度上看到了它的情况,但我真的不认为这是一个可行的选择......它似乎很难维护,相当矫枉过正,几乎没有必要。

然而,我可以看到它用于模板前向声明,这是相当重的。但对于简单的课程呢?维护起来似乎很痛苦,并且会创建大量几乎空的包含文件,这些文件的用途非常小……值得这么麻烦吗?

这是一个例子:

// Class.h
class Class
{
    Class();
    ~Class();
};

// ClassFwd.h
class Class;

// Class.cpp
Class::Class()
{
}

Class::~Class()
{
}

我的问题

你们觉得怎么样?这是一个好的做法吗?

注意 我最感兴趣的是这种做法的论据,看看我是否错过了一些能让我同意斯科特·迈耶斯的观点的东西。

In Effective C++ (3rd edition), Scott Meyers, in Item 31, suggests that classes should have, on top of their classic Declaration (.h) and Definition (.cpp) files, a Forward Declaration Include File (fwd.h), which class that do not need the full definition can use, instead of forward declaring themselves.

I somewhat see the case for it, but I really don't see this as a viable option... It seems very hard to maintain, rather overkill and hardly necessary.

I can, however, see its use for template forward declarations, which are rather heavy. But for simple classes? It seems to be that it's a pain to maintain and will create a whole lot of almost empty include files that serve a very small purpose... is it worth the hassle?

Here's a example:

// Class.h
class Class
{
    Class();
    ~Class();
};

// ClassFwd.h
class Class;

// Class.cpp
Class::Class()
{
}

Class::~Class()
{
}

My question:

What do you guys think? If this a good practice?

NOTE I am mostly interested in the arguments FOR this practice, to see if I missed something that would make me agree with Scott Meyers.

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

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

发布评论

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

评论(4

城歌 2024-10-04 15:22:54

我为所有库使用了前向声明头文件。库通常具有以下结构:

lib/
  include/
    class headers + Fwd.h
src/
  source files + internal headers

lib/include 目录将包含所有公共类标头以及一个前向声明标头。这使得库在包含方面变得轻量级。该库之外的任何标头仅包含前向标头 (Fwd.h),而该库之外的源包含必要的完整标头。还可以提供一个方便的标头 (Lib.h),其中包含所有其他标头,以便在源文件中使用。

前向声明头中放置的另一件事是 shared_ptrtypedef,特别是在具有返回实现指针的工厂类的继承层次结构的情况下。

上述内容对于具有大量内部库的大型应用程序很有用。对于这种情况,上述内容的改进是将公共标头放置在 lib/include/lib 中。这样,您的库的客户端就必须包含 lib/...。将其视为标头的命名空间。

祝你好运!

I used forward declaration header files for all my libraries. A library would typically have this structure:

lib/
  include/
    class headers + Fwd.h
src/
  source files + internal headers

The lib/include directory would contain all public classes headers along with one forward declarations header. This made the library light-weight on the include side. Any header outside of this library only includes the forward header (Fwd.h), while sources outside of this library includes the necessary complete headers. One can also provide a convenience header (Lib.h) that includes all the other headers, for use in source files.

Another thing to place in the forward declaration header is typedefs for shared_ptr, especially in the case of an inheritance hierarchy with factory classes that return pointers to implementations.

The above is useful for larger applications with lots of internal libraries. A refinement of the above for this case would be to place the public headers in lib/include/lib. This way clients of your library would have to include lib/.... Think of this as a namespace for your headers.

Good luck!

ぺ禁宫浮华殁 2024-10-04 15:22:54

将一个简单的 class Whatever; 放在自己的标头中没有任何优点,而且有很多缺点。

特别是在访问标头可能非常耗时的情况下,可以使用简单的前向声明来避免访问标头;将它们放在自己的标题中会达不到目的...

对于模板化的东西,正如您所注意到的,这是另一回事。例如,从标准库中查看

干杯&嗯。

Placing a simple class Whatever; in its own header has no advantages and lots of disadvantages.

Especially in the case where accessing a header can be time consuming, one uses simple forward declarations to avoid accessing headers; putting them in their own headers would defeat the purpose...

With templated things, as you note, it's a different matter. E.g. check out <iosfwd> from the standard library.

Cheers & hth.

羁绊已千年 2024-10-04 15:22:54

这种做法让代码使用者不必考虑一个类是常规类还是模板类。用户只需#inludes“corresponding_fwd.h”文件并具有类引用。减少用户烦恼是一件好事。但如果它是一个小项目或类的创建者是唯一的类用户,那么它可能会更烦恼。所以,这取决于。

The practice allows the code user not to think about whether a class is regular or template. The user just #inludes "corresponding_fwd.h" file and has a class reference. One less annoyance for the user is A Good Thing. But if it's a small project or class' creator is the only class' user then it might be more annoyance. So, it depends.

我的痛♀有谁懂 2024-10-04 15:22:54

如果您有一个大型解决方案,这是处理固有依赖性的唯一机会:

struct A {
    B* m_pB;
};

struct B {
    A* m_pA;
};

现在 A 和 B 可能合理地位于不同的头文件中,甚至可能位于不同的项目中。然而,它们的依赖性并不是某种设计缺陷,而是完全合乎逻辑和必要的。你做什么工作?

  1. 首先为每个所需项目包含一个 Types.h 前向声明标头,即前向声明每个类没有自己的头文件。
  2. 然后包含所有必需项目的 Class.h。这些标头需要前向声明才能编译。
  3. 包括主项目的标题。

在一个相当大的解决方案(500k LOC)中,我发现这种模式非常容易管理。否则,如果您更改类声明,您在哪里可以找到您可能在任意数量的其他头文件中单独进行的所有前向声明?

If you have a large solution this is your only chance to handle the inherent dependencies:

struct A {
    B* m_pB;
};

struct B {
    A* m_pA;
};

Now A and B may reasonably be in different header files, maybe even different projects. Yet, their dependency is not some design defect but entirely logical and necessary. What do you do?

  1. First include a single Types.h forward-declarating header for eeach required project, i.e., the forward declaration does not have its own header file per class.
  2. Then include the Class.h of all required projects. These headers will require forward declarations to compile.
  3. Include the headers of the main project.

In a rather large solution (500k LOC) I've found this pattern to be very easily manageable. Otherwise, if you change a class declaration, where do you find all forward declarations that you may have made individually in any number of other header files?

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