【问题标题】:What are the uses of entire headers for forward declarations?前向声明的整个标头有什么用途?
【发布时间】:2026-01-11 10:15:02
【问题描述】:

我见过使用#include 的前向标头的代码,否则会有前向声明。 “前向标头”是指仅包含前向声明的标头。因此,如果 class.h 包含模板,您可能有 class.cpp、class.h 和 class_fwd.h 或只有 class.h 和 class_fwd.h。

Boost 中有一些例子,它有一些file_fwd.hpp 文件。

什么时候创建和包含前向标头比显式前向声明更可取?什么时候不是?这种做法的优点和缺点是什么?是否应该为所有标头创建一个转发标头?

这个问题本质上是一样的:

Forward declaration include, on top of declaration include (ClassFwd.h + Class.h)

为什么我对那个问题的答案不满意:

  • Daniel Lidström 的回答描述了他所做的相关事情,但没有具体解决这个问题。
  • Sebastian 的回答主要解释了为什么通常使用前向声明,然后在类似于 Daniel Lidström 所描述的模式上使用 cmet。
  • Dialectus 的回答含糊不清,但确实暗示模板是使用前向标头的一个原因。
  • 干杯和hth。 - Alf 的答案与 Dialecticus 的答案相似。

【问题讨论】:

  • 好吧,如果一个库提供了很多类型(例如<iostream>),并且用户只需要在其标头中进行前向声明是合理的(例如std::ostream & foo(std::ostream &)),那么这只是礼貌让库提供一个仅前向声明的标头。
  • 解释?这是指我链接的副本吗?我不是说了吗?
  • 如果有一个问题本质上是相同的,但您想要一个更好的答案,获得它的一种方法是提供小额奖励以吸引注意力。添加评论为什么您认为当前的答案不令人满意。免责声明:我认为我无法给出比现有答案更好的答案。

标签: c++ include forward-declaration


【解决方案1】:

如果前向声明保存在标头中,则前向标头可以包含在主标头和/或实现文件中,以便编译器可以检查是否违反了单一定义规则。 (例如模板参数的数量不匹配)

这与实际定义函数时应显示带有函数原型的标头的原因基本相同。

此外,“不要重复自己”指南建议不要多次重复相同的声明。不是因为复制会浪费磁盘空间,甚至是因为难以将更改传播到多个位置(尽管这经常被引用),而是为了防止存在不兼容版本的可能性。

【讨论】:

  • 只是为了确保,您说的是聚合前向声明的前向标头(尤其是对于整个库),但绝对没有理由创建前向标头来匹配每个单独的标头,对吗?跨度>
  • 这些好处同样适用于拆分或聚合的前向标头。我会根据事物的密切程度进行汇总。
  • 最后一件事 - “主标题”到底是什么意思?这是作为使用 lib 的单个包含创建的标头吗?
  • @Praxeolitic:我的意思是包含完整类定义的标题。