84

<iosfwd>标头是做什么用的?为什么有必要?

有什么例子吗?

4

3 回答 3

78

这样您就可以在自己的头文件中声明依赖于 iostream 类型声明的方法,而不必#include使用 iostream 头文件本身,因为这些头文件庞大、复杂且编译速度慢。

这是一个简单的例子:

// foo.h
#include <iosfwd>

void sucker(std::iostream& is);

 

// foo.cc
#include <iostream>

void sucker(std::iostream& is) {
    is >> somevar;
}
于 2010-11-29T03:54:58.167 回答
44

正如@Marcelo Cantos提到的那样,您可以在不包括完整定义的情况下包含 iostream 类和函数的声明。在 C 和 C++ 中,声明是一个声明,它说“这是某物的名称(函数/类/等),但除了它的名称之外,我不会告诉你更多关于它的信息”。对于函数,这意味着函数的名称,而不是包含函数代码的主体。对于一个类,这意味着类的名称,而不是类的任何成员变量或方法。

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

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

通过只包括声明而不是定义,编译器必须处理的代码总量要少得多,因此编译将进行得更快。

为了让您了解正在处理多少代码,以下是我的本地实现中包含多少代码:

# 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 行代码。那是在编译您在源文件中关心的实际代码之前!

于 2010-11-29T04:12:51.160 回答
17

基本上你使用的时候<iosfwd>是因为你想消除编译时的依赖。

您使用<iosfwd>而不是传统的流标头(<iostream>和朋友),这样您就可以避免包含整个流媒体内容的定义。与<iosfwd>您一起只是对所有流媒体内容进行前向声明。

我发现这个链接特别有用: http ://www.gotw.ca/gotw/007.htm

于 2013-07-17T08:33:09.447 回答