【问题标题】:C/C++ Forward declaration vs. IncludeC/C++ 前向声明与包含
【发布时间】:2011-12-12 23:07:53
【问题描述】:

当你包含一些文件时会发生什么,当你转发声明一些函数/类时会发生什么?如果两个文件包含同一个文件,第一个会成功读取所有函数,第二个会失败但仍然可以使用这些函数??

当我转发声明某个函数时会发生什么?这个函数现在是否“保存”了,我可以在任何地方使用它,还是只知道同一个文件?那么为什么两个带有包含的文件(到一个带有保护的文件)会起作用?

我可以将所有内容都包含在主目录中而不再打扰吗?

编辑:

为什么 cpp 文件应该包含它们的标题?如果我不包括它们怎么办?

【问题讨论】:

  • 前向声明只定义了编译单元的函数。对于要在其中使用函数的每个编译单元,您必须在函数声明中包含头文件。
  • @freedrull 前向声明不定义,它们声明,因此得名。此外,前向声明函数与前向声明用户定义类型不同。

标签: c++ header include forward-declaration


【解决方案1】:

当你包含一些文件时会发生什么,当你转发声明一些函数/类时会发生什么?

当您包含一个文件时,其内容会被预处理器“复制并粘贴”到包含源中。当您转发声明一个函数/类时,您是在声明一个不完整的类型,让翻译单元的其余部分知道存在具有该名称的函数/类,并使其在允许不完整声明的上下文中可用。

如果两个文件包含同一个文件,第一个会成功读取所有函数,第二个会失败但仍然可以使用这些函数??

如果包含的文件包含正确的include guards,则同一翻译单元中的第二个包含实际上将是空操作。如果两个不同的源文件包含同一个头文件,则完整的内容将包含在两个文件中。

当我转发声明某个函数时会发生什么?这个功能现在是“保存”了,我可以在任何地方使用它还是只知道同一个文件?那么为什么两个包含包含的文件(到一个带有保护的文件)会起作用?

该函数只能在包含前向声明的翻译单元中使用。通常每个源文件 (.cpp) 是一个不同的翻译单元,宏定义(那些标头保护)以及声明/定义在该翻译单元内是有效的。 Header guards 防止同一个头文件被多次包含在同一个翻译单元中,以防止多个声明错误。

【讨论】:

  • 添加了包含守卫的链接,认为它可能对 OP 有所帮助。
【解决方案2】:

当你包含一些文件时发生了什么以及正在发生什么 当你转发声明一些函数/类?

当您include 一个文件时,预处理器有效地将整个included 文件复制粘贴到执行includeing 的文件中。当您转发声明一个函数/类时,您是在告诉编译器它存在,但您不需要整个头文件。当您有循环依赖时,这是必需的,并且大大减少了其他地方的编译时间。

如果两个文件包含同一个文件,第一个读取成功 第二个的所有功能都将失败,但仍然可以使用 函数??

如果同一个文件在一个翻译单元(.cpp 文件)中包含两次,那么两者都会“成功”,但如果标题包含任何类型的保护,则第二次不会加载任何内容,因为预处理器已经将它“复制”到翻译单元中,并且第二次这样做会复制所有内容,这将是一个错误。因此,所有涉及的文件都可以使用到目前为止包含的所有标头中的所有功能。

当我转发声明某个函数时会发生什么?是这个功能吗 现在“已保存”,我可以在任何地方使用它,或者它仅以相同的方式而闻名 文件?那么为什么两个包含包含的文件(到一个带有保护的文件)会起作用?

是的,如果您在标头中前向声明函数/类,则它可以被包含该标头的任何其他文件使用。

我可以将所有内容都包含在主目录中而不再打扰吗?

大概吧。一旦你遇到更复杂的例子,你就会得到循环依赖,这要求某些东西以一定的顺序声明和/或定义。除此之外,是的。您可以在 main 中包含所有内容并保持简单。但是,您的代码将永远编译。

为什么 cpp 文件应该包含它们的标题?如果我不包括它们怎么办?

那么.cpp 文件将不知道在其自身之外存在其他任何东西。不是很有用。

【讨论】:

    【解决方案3】:

    简短回答: 转发一个类/函数允许编译器实际上不必编译整个类/函数,除非需要。

    长答案: 转发一个类/函数就像声明一个类/函数而不定义它。您承诺稍后定义它,但现在您只想通知编译器它存在。您通常在头文件中执行这些正向减速。这通常会导致更快的编译时间,因为在包含您的头文件的 .cpp 文件中,只有那些实际需要您转发的类并包含它的适当头文件的文件才需要实际编译包含的类的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-29
      • 2021-12-25
      相关资源
      最近更新 更多