为什么我应该在使用命名空间std?</iostream>后包含头文件<iostream>

时间:2014-09-28 16:09:16

标签: c++ std header-files iostream

由于命名空间std已经有包含函数定义的c ++库(如果我是对的),那么为什么我们在它上面包含头文件?由于命名空间std包含c ++标准库,因此我没有理由单独包含它的声明。

5 个答案:

答案 0 :(得分:7)

执行#include <iostream>时,会导致源文件中包含一组类和其他内容。对于iostream和大多数标准库头文件,他们将这些内容放在名为std的名称空间中。

所以#include <iostream>的代码看起来像这样:

namespace std { 
    class cin  { ... };
    class cout { ... };
    class cerr { ... };
    class clog { ... };
    ...
}

所以在这一点上,你可以编写一个看起来像这样的程序:

#include <iostream>

int main() {
    std::cout << "hello\n";
    return 0;
}

现在,有些人认为std::cout过于冗长。所以他们这样做:

#include <iostream>
using namespace std;

int main() {
    cout << "hello\n";
    return 0;
}

就个人而言,我建议不要这样做,如果您确实认为std::cout过于冗长,那么我建议您使用较小的using语句。

#include <iostream>
using std::cout;

int main() {
    cout << "hello\n";
    return 0;
}

如果您想知道为什么我会推荐using namespace std,那么我会转发给stackoverflow上的以下两篇帖子:

答案 1 :(得分:5)

编译器本身没有任何命名空间中的东西的定义(无论是std还是其他命名空间)。这是源文件和头文件的作用。

using namespace std;告诉编译器的是“如果在当前命名空间中找不到某个名称,请同时查看std命名空间”。

#include <iostream>告诉编译器,您希望源代码中包含名为iostream的标头内容。这将为编译器提供执行cincout和许多其他相关功能的代码。此文件的内容声明为namespace std { ... all the stuff goes here ... }

命名空间的使用允许在namespace math;工作的其他人不必担心“嗯,我现在该做什么,我需要一个入口数量的计数器,我们称之为cin - 但坚持下去,是否曾经在任何地方使用过?“

这可能不是最好的例子,但在大型项目中,跟踪事物及其名称变得越来越难。 C ++是一种用于数百万行代码的大型项目的语言 - 现在,如果你使用了某个特定的名字,它就会变得难以记住。命名空间确保您不必在特定命名空间之外担心它。

(哦,在我的代码中,我倾向于不使用using namespace std;,而是写std::cout << "Hello, World!" << std::endl; - 这有助于明确我在这里使用的coutstd一个,而不是别的。当你有几个具有相似内容的命名空间时,这是特别有用的,比如我自己的编译器,我的编译器有它的功能,std命名空间提供一些东西和llvm编译器 - 如果我在代码的开头粘贴using namespace llvm;,那么很难跟踪Type* p = ...;是来自LLVM还是我自己的某些部分代码。)

答案 2 :(得分:0)

  

...为什么我们在它上面包含头文件?

是的,这里有一些很大的混乱。

命名空间

命名空间是一种将函数名称等符号分类或组合在一起的方法。

命名空间旨在防止不同软件组件(如库)之间的名称冲突。

作为标准语言一部分的函数分组在命名空间std下。

C ++语言提供语句以减少使用命名空间时的键入量。其中之一是using声明。

标题(包含)文件

编写程序时,编译器不需要自动包含所有符号定义,例如函数声明。您需要告诉它您计划使用哪些功能。

例如,我可以在不使用sort组中的advancealgorithm函数的情况下编写程序。因此,我不会包含头文件algorithm

C ++语言旨在“使用您需要的东西”,换句话说,我们可以通过仅包含我们需要的功能来创建小程序。

其他平台

顺便说一下,除了你正在使用的平台外,还有很多其他平台。

某些平台需要适合小内存区域,并且可能没有键盘或显示器(例如嵌入式控制器)。

所以请记住,C ++被定义为支持从小型和受约束到大型且几乎无约束的系统的平台。

因此,对&#34;的要求仅包括您需要的内容&#34;主题。

摘要

总之,由于C ++语言不会自动地神奇地提供整个库的定义,包括模板库,因此需要告诉编译器要使用哪些函数组。这样可以更快地进行编译,因为只指定了所需的头文件。

注意:一些商店和图书馆用品喜欢使用 Monolith 包含系统。这意味着它们有一个包含整个库的包含文件,无论您使用的是一个函数还是多个函数。 windows.h是一个典型的例子。一个不利之处在于,当一个头文件被更改时,一切都需要重建。使用分隔的包含文件,只需要重建包含已更改的头文件的组件。

答案 3 :(得分:0)

使用预处理器指令#include与c ++本身一样古老。并且它不会更快消失。在C ++命名空间中不会将任何内容导入到您的程序中,它只是定义了特定头文件函数的范围。因此,两者都是必需的。 Click here了解为何使用命名空间。

答案 4 :(得分:0)

您的问题是:namespace std具有iostream库的所有函数/类的定义。因此,只需使用using namespace std就足以调用或使用coutiostream库的所有其他功能。为什么我们必须使用第#include <iostream>行?似乎是多余的。

大致上,我们可以认为iostream库具有两个文件:标头和实现/源文件。这两个文件具有一个名为std的命名空间。头文件仅包含iostream库将要使用的类或函数或变量的声明或正向声明,并且这些声明或正向声明位于std命名空间下。实现文件包含类,函数或变量的实际实现,并且这些实现位于std命名空间下;此文件也称为源文件。

因此,如果您在using namespace std文件编译器中仅使用#include <iostream>而没有main.cpp,则会在std文件中搜索main.cpp命名空间,但是这里没有。您将得到编译器错误。

现在,如果您在#include <iostream>中加入这一行main.cpp,则预处理器将转到iostream的头文件,并将std名称空间及其代码复制到我们的{ {1}}。并且链接程序会将main.cpp的预编译(因为iostream是SLT,因此它带有预编译的编译器)源/实现文件链接到您的iostream。现在要使用位于main.cppiostream命名空间下的std的函数或变量,我们必须使用范围解析运算符(::)告诉编译器main.cpp,{ {1}}和cout的其他功能位于cin命名空间。因此,我们只需这样写:iostreamstd

现在对某些人来说,键入std::cin似乎是多余的,因此他们通过使用此std::cout告诉编译器“嘿,如果您在全局/当前名称空间中找不到任何变量/函数/类,在std::名称空间中查看。”尽管这不是最佳实践,但这是另一个需要讨论的话题。因此,您对using namespace std命名空间包含C的所有SLT函数/类/变量的所有定义的假设在大多数情况下是不正确的,而std命名空间仅包含STL的声明是正确的假设。 / p>

这是一个伪实现,如何将std libray添加到我们的代码文件中: std

iostream

iostream.h

// This is header file that only contains the
// functions declarations.
namespace std_dum
{
    int add(int x, int y);

    int mult(int x, int y);
}

iostream_dum.cpp

// This is source file of iostream_dum.h header
// which contains the implementation of functions.

#include "iostream_dum.h"

namespace std_dum
{

    int add(int x, int y)
    {
        return x + y;
    }

    int mult(int x, int y)
    {
        return x * y; 
    }

}

要查看预处理后我们的main.cpp文件会发生什么,请运行以下命令:#include <iostream> #include "iostream_dum.h" int main() { std::cout << std_dum::add(100, 200) << '\n'; std::cout << std_dum::mult(100, 200) << '\n'; return 0; }

这里的main.cpp大致如下:

g++ -E main.cpp iostream_dum.cpp

为清楚起见,我丢弃了预处理器从main.cpp复制的所有代码。

现在应该很清楚了。

相关问题