繁体   English   中英

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

[英]why should i include the header file <iostream> after using the namespace std?

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

当您执行#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 的另外两篇文章:

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

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

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

命名空间的使用允许其他人在namespace math;工作namespace math; 不必担心“嗯,我现在该怎么办,我需要一个入口数量的计数器,让我们称之为cin - 但是等等,它在任何地方都使用过吗?”。

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

(哦,在我的代码中,我倾向于不使用using namespace std; ,而是写std::cout << "Hello, World!" << std::endl; - 这有助于说明cout我'我在这里使用的是std ,而不是其他东西。当您有多个具有相似内容的命名空间时,这特别有用,例如在我自己的编译器中,我的编译器具有它的功能, std命名空间提供了一些东西,以及llvm编译器的事情 - 如果我坚持using namespace llvm;在代码的开头,很难跟踪Type* p = ... ; 是来自 LLVM 还是我自己代码的某些部分。)

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

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

命名空间

命名空间是一种对函数名称等符号进行分类或分组的方法。

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

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

C++ 语言提供了在使用命名空间时减少输入量的语句。 其中之一是using语句。

头(包括)文件

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

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

C++语言被设计成“用你所需要的”,换句话说,我们可以通过只包含我们需要的函数来创建小程序。

其他平台

顺便说一句,除了您正在使用的平台之外,还有许多其他平台。

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

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

因此,要求“仅包含您需要的内容”主题。

概括

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

注意:一些商店和图书馆用品喜欢使用Monolith包含系统。 这意味着他们有一个包含整个库的包含文件,无论您使用一个函数还是多个函数。 windows.h就是一个经典的例子。 一个不利因素是,当一个头文件被更改时,所有内容都需要重新构建。 使用分离的包含文件,只需要重新构建包含更改的头文件的组件。

预处理器指令 #include 的使用与 C++ 本身一样古老。 它不会很快消失。在 C++ 命名空间中,不会将任何内容导入您的程序,它只是定义了特定头文件功能的范围。因此,两者都是必需的。 单击此处了解为什么要使用命名空间。

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

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

所以,如果你只使用using namespace std没有#include <iostream>在你main.cpp文件的编译器将搜索std命名空间在你main.cpp文件,但它是不是在这里。 你会得到编译器错误。

现在,如果您在main.cpp包含此#include <iostream>行,预处理器将转到iostream的头文件并将std命名空间及其代码复制到我们的main.cpp 和连接器将链接预编译(如iostream源/执行文件是一个SLT所以它带有编译器,预建) iostreammain.cpp 现在要使用位于main.cpp std命名空间下的iostream函数或变量,我们必须使用作用域解析运算符 (::) 来告诉编译器coutciniostream其他功能位于std命名空间。 因此我们简单地写成这样: std::cinstd::cout

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

这是如何将iostream libray 添加到我们的代码文件中的虚拟实现: 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样子:

namespace std_dum
{
    int add(int x, int y);

    int mult(int x, int y);
}

int main()
{
 std::cout << std_dum::add(100, 200) << '\n';
 std::cout << std_dum::mult(100, 200) << '\n';

 return 0;
}

namespace std_dum
{

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

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

 }

为了清楚起见,我丢弃了预处理器从#include <iostream>复制的所有代码。

现在应该很清楚了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM