c++一开始就有这么两行代码
#include<iostream>
using namespace std;
基本上所有教科书都会解释#include<…>是一个预编译头,后面尖括号是头文件。接下来下一行是使用标准命名空间std。然后就没有然后了,或者有然后也是各种解释不清楚的东西。现在想用一种清晰直观的解释来说明第二行的命名空间的作用和它与头文件到底有什么关系。
此外,还可以从《Effective C++》条款23(p100、p101)中通过c++标准库的std命名空间的组织形式进行了解;
首先说命名空间(namespace)。
命名空间的主要作用就是为了解决“重名”带来的麻烦。
对于“重名”,其他的一些资料和网上的各种大牛给出了一种形象的解释:学校中有很多人都叫“张三”,但是他们都分在不同的班级,不同的“班号”就能让我们将所有的“张三”区别开,因此这里的“班号”就相当于“命名空间”。
除去命名空间,c++也有很多方式解决这个问题:
1.创建一个类,然后创建一个类的对象,不同的类中可以含有同名的变量/函数(java一般称为方法),通过不同类的对象来调用不同的同名函数,从而防止重名带来的问题;
2.函数重载;
//可能还有别的方式,以我目前具备的知识储备能想到的就这么多
但由于全局变量/对象/函数的存在,以上方法有可能会“失效”。因此命名空间被发明出来解决这个问题。
我们先来看如何创建自己的命名空间,这对理解为何要有using namespace std;
这行代码非常有帮助
很简单,非常类似于创建结构体:
namespace my_ns
{
//your code...
}
在使用的时候就可以using namespace my_ns;
回过头来解释之前的问题。我们很可能会去想,cin、cout等不已经在头文件iostream中了么,为何还要包含标准命名空间std?给人一种似乎#include没用的感觉,又好像cin、cout等一批东西同时存在于这两个“分立”的东西里。
实际的答案是,确实标准的输入输出同时存在于头文件和命名空间中,但头文件和命名空间并不是“分立”的,而是在头文件中包含了标准的命名空间std。应该这么理解:头文件iostream中有这么几行定义了标准命名空间std的代码:
namespace std
{
...
cin...
cout...
...
}
当我们没有using namespace std或者使用std::cin/std::cout/…的时候,cin,cout是不可见的,也就是说即使我们包含了iostream,但由于没有使用标准命名空间std,使得该命名空间内所有的内容我们无法使用。
这就说明了头文件iostream和标准命名空间std的关系——正如很多人所说,这俩是两个不同的东西,但是由于它们的“包含”关系(在头文件中定义了命名空间std),我们不能说它们是完全独立的。要想理解好为何会有开头的两行,我认为弄清楚这个过程和原理是必不可少的。
要另外强调的是iostream和iostream.h是不同的,后者是为了向前兼顾c语言的产物,在新版本的VS中已经删去。iostream.h可以理解为包含了命名空间std的iostream。