什么是<iosfwd>头文件?

99
3个回答

96

这是为了在你自己的头文件中声明依赖于 iostream 类型声明的方法,而不必包含 iostream 头文件本身。iostream 头文件很大,复杂且编译速度慢。

以下是一个简单的示例:

// foo.h
#include <iosfwd>

void sucker(std::iostream& is);

 

// foo.cc
#include <iostream>

void sucker(std::iostream& is) {
    is >> somevar;
}

1
你能详细解释一下它是如何使用引用传递的吗? - wp2
4
它只是声明类型而不定义它们。为什么不亲自瞧一眼呢?它非常简短。 - Marcelo Cantos
1
在foo.cc中使用#include <iostream>的好处是什么,而不是直接在foo.h中使用它? - wp2
14
是的,但只需要在需要声明的.cpp文件中进行,而不是在每个使用foo.h的.cpp文件中都进行。 - Marcelo Cantos
1
iosfwd除了命名空间std { class istream; cass ostream; }之外还有其他内容吗? - uuu777

54

正如@Marcelo Cantos所说,这是为了让您可以包含iostream类和函数的声明,而无需包含完整的定义。在C和C++中,declaration(声明)是一种语句,它表示“这里是某个东西的名称(函数/类等),但我不会告诉你更多关于它的信息,除了它的名称”。对于函数来说,这意味着函数的名称,但并不包括包含函数代码的函数体。对于类来说,这意味着类的名称,但不包括任何类的成员变量或方法。

相反,definition(定义)是完整的定义:函数体、类成员等。

通常情况下,您只需要使用某些东西的声明——对于函数来说,您不需要知道函数体的样子就可以调用它(除了模板或内联函数的情况)。同样地,对于一个类,如果你传递指向该类实例的指针或引用,你不需要知道该类有哪些成员。但是,一旦您需要访问成员变量或调用类方法,那么您就需要完整的定义。

仅包含声明而不是定义,编译器需要处理的总代码量要少得多,因此编译将更快地进行。

为了给您一个代码处理量的概念,这是我本地实现中包含的代码量:

# The following commands create a source file that includes a single header
# file (on stdout), preprocess it with g++ -E, and then count how many lines
# are in the resulting preprocessed output
$ echo '#include <iosfwd>' | g++ -E -xc++ - | wc
    2598    6534   57875
$ echo '#include <iostream>' | g++ -E -xc++ - | wc
   25631   59613  631998

如果一个文件包含了<iosfwd>,编译器需要从各种头文件中处理2598行代码,而如果一个文件包含了<iostream>,则需要处理整整25631行代码。这还没有编译你在源文件中关心的实际代码!


以下命令的工作原理是什么: $ echo '#include <iosfwd>' | g++ -E -xc++ - | wc 我尝试运行以下命令,但出现了一些错误: $ echo '#include <QtGlobal>' | g++ -E -xc++ - | wc 我错在哪里了? - beparas

25
基本上当你使用<iosfwd>时,是因为你想消除编译时的依赖关系。
你使用<iosfwd>而不是传统的流头文件(例如<iostream>和相关文件),这样就可以避免包含整个流事物的定义。通过<iosfwd>,你只是在进行所有流事物的前向声明。
我发现这个链接特别有用:http://www.gotw.ca/gotw/007.htm

4
这种方式比已有的两个回答更有深度,而且这两个回答已经存在超过2年了。 - Christian Rau
我原本以为这更多是构建优化:编译<iosfwd><iostream>要快得多。或者你所说的应用程序是你的主要重点吗? - user1084944
2
@ChristianRau,为了帮助您和谷歌用户,我真的很欣赏这个答案的简洁性。我不需要其他答案中的任何废话,只需要魔术词“前向声明”,而您可能错过了,在此页面上除了问题标签(在此答案之后添加)外,它似乎没有出现在其他地方。 - Sz.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接