[英]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
的头文件的内容包含在您的源代码中。 这将为编译器提供执行cin
、 cout
和许多其他相关功能的代码。 这个文件的内容被声明为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
组中的sort
或advance
函数的情况下编写程序。 因此我不会包括头文件algorithm
。
C++语言被设计成“用你所需要的”,换句话说,我们可以通过只包含我们需要的函数来创建小程序。
顺便说一句,除了您正在使用的平台之外,还有许多其他平台。
某些平台需要适合小内存区域,并且可能没有键盘或显示器(例如嵌入式控制器)。
所以请记住,C++ 被定义为支持从小型受限系统到大型且几乎不受约束的系统的平台。
因此,要求“仅包含您需要的内容”主题。
总之,由于 C++ 语言不会自动、神奇地提供整个库的定义,包括模板库,您需要告诉编译器您要使用哪些函数组。 这允许更快的编译,因为只指定了所需的头文件。
注意:一些商店和图书馆用品喜欢使用Monolith包含系统。 这意味着他们有一个包含整个库的包含文件,无论您使用一个函数还是多个函数。 windows.h
就是一个经典的例子。 一个不利因素是,当一个头文件被更改时,所有内容都需要重新构建。 使用分离的包含文件,只需要重新构建包含更改的头文件的组件。
预处理器指令 #include 的使用与 C++ 本身一样古老。 它不会很快消失。在 C++ 命名空间中,不会将任何内容导入您的程序,它只是定义了特定头文件功能的范围。因此,两者都是必需的。 单击此处了解为什么要使用命名空间。
您的问题是: namespace std
具有iostream
库的函数/类的所有定义。 因此,简单地使用using namespace std
就足以调用或使用cout
或iostream
库的所有其他功能。 为什么我们必须使用行#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所以它带有编译器,预建) iostream
您main.cpp
。 现在要使用位于main.cpp
std
命名空间下的iostream
函数或变量,我们必须使用作用域解析运算符 (::) 来告诉编译器cout
、 cin
和iostream
其他功能位于std
命名空间。 因此我们简单地写成这样: std::cin
和std::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.