您的问题是:namespace std 具有 iostream 库的所有函数/类的定义。所以只需使用using namespace std 就足以调用或使用cout 或iostream 库的所有其他功能。为什么我们必须使用#include <iostream> 行?这似乎是多余的。
我们大致可以认为iostream 库有两个文件:头文件和实现/源文件。这两个文件有一个名为std 的命名空间。头文件仅包含 iostream 库将使用的类或函数或变量的声明或前向声明,这些声明或前向声明位于 std 命名空间下。实现文件包含类或函数或变量的实际实现,这些实现位于std 命名空间下;此文件也称为源文件。
因此,如果您在main.cpp 文件中仅使用using namespace std 而没有#include <iostream>,编译器将在您的main.cpp 文件中搜索std 命名空间,但它不在这里。你会得到编译器错误。
现在,如果您在main.cpp 中包含此#include <iostream> 行,预处理器将转到iostream 的头文件并将std 命名空间及其代码复制到我们的main.cpp 中。链接器会将iostream 的预编译(因为iostream 是SLT,因此它带有带有预编译的编译器)源/实现文件链接到您的main.cpp。现在要使用位于main.cpp 中的std 命名空间下的iostream 的函数或变量,我们必须使用范围解析运算符(::) 来告诉编译器cout、cin 和@987654350 的其他功能@ 位于 std 命名空间。因此我们简单地写成这样:std::cin,和std::cout。
现在输入 std:: 对某些人来说似乎是多余的,所以他们通过使用 using namespace std 告诉编译器“嘿编译器,如果您在全局/当前命名空间中找不到任何变量/函数/类,请查看 @ 987654356@ 命名空间。”虽然这不是最佳实践,但这是另一个要讨论的话题。因此,您假设 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>复制的所有代码。
现在应该很清楚了。