using namespace 引用命名空间理解

来源:互联网 发布:mac 安装输入法 编辑:程序博客网 时间:2024/05/16 01:57

所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。

 

 一 、<iostream>和<iostream.h>格式不一样  前者没有后缀,实际上,在你的编译器include文件夹里面可以看到,二者是两个文件,打开文件就会发现,里面的代码是不一样的。 后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。 因 此,当使用<iostream.h>时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;当使用< iostream>的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。

编辑本段二、namespace是指标识符的各种可见范围

  C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。 由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:

1、直接指定标识符。

  例如std::ostream而不是ostream。完整语句如下: std::cout << std::hex << 3.4 << std::endl;

2、使用using关键字。

  using std::cout; using std::endl; using std::cin; 以上程序可以写成 cout << std::hex << 3.4 << endl;

3、最方便的就是使用using namespace std

  例如:

  #include<iostream>

  #include<sstream>

  #include<string>

  using namespace std;

  这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全局变量一样。那么以上语句可以如下写: cout << hex << 3.4 << endl; 因为标准库非常的庞大,所以程序员在选择的类的名称或函数名时就很有可能和标准库中的某个名字相同。所以为了避免这种情况所造成的名字冲突,就把标准库中的一切都放在名字空间std中。但这又会带来了一个新问题。无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间下的。 所以就有了<iostream>和<iostream.h>等等这样的头文件,一个是为了兼容以前的C++代码,一个是为了支持新的标准。 命名空间std封装的是标准程序库的名称,标准程序库为了和以前的头文件区别,一般不加".h"

4、简便理解:

C++中采用的是单一的全局变量命名空间。在这单一的空间中,如果有两个变量或函数的名字完全相同,就会出现冲突。当然,你也可以使用不同的名字,但有时我们并不知道另一个变量也使用完全相同的名字;有时为了程序的方便,必需使用同一名字。比如你定义了一个变量string   user_name,   有可能在你调用的某个库文件或另外的程序代码中也定义了相同名字的变量,这就会出现冲突。命名空间就是为解决C++中的变量、函数的命名冲突而服务的。解决的办法就是将你的strTemp变量定义在一个不同名字的命名空间中。就好像张家有电视机,李家也有同样型号的电视机,但我们能区分清楚,就是因为他们分属不同的家庭。

例如:

#include   <iostream>
#include   <string>
using   namespace   std;


//using   namespace编译指示,使在C++标准类库中定义的名字在本程序中可以使用
//否则,iostream,string   等c++标准类就不可见了,编译就会出错。

//两个在不同命名空间中定义的名字相同的变量

namespace   myown1{

string   user_name   =   "myown1 ";
}
namespace   myown2{

string   user_name   =   "myown2 ";
}

int   main()
{
cout < <   "/n "
< <   "Hello,   "  
< <   myown1::user_name //用命名空间限制符myown1访问变量user_name
< <   "...   and   goodbye!/n ";

cout < <   "/n "
< <   "Hello,   "  
< <   myown2::user_name   //用命名空间限制符myown2访问变量user_name
< <   "...   and   goodbye!/n ";

return   0;
}

当然,我们也可以使用程序开头的预编译指示来使用命名空间中的名字。使用预编译指示的好处在于在程序中不必显式地使用命名空间限制符来访问变量。以上主程序可修改为:  
int   main()
{
using   namespace   myown1;
cout < <   "/n "
< <   "Hello,   "  
< <   user_name
< <   "...   and   goodbye!/n ";

// using   namespace   myown2;
cout < <   "/n "
< <   "Hello,   "  
< <   myown2::user_name   //用命名空间限制符myown2访问变量user_name
< <   "...   and   goodbye!/n ";

return   0;
}

但第二个变量必需用命名空间限制符来访问,因为此时myown1空间中的变量已经可见,如果不加限制,编译器就会无法识别是那一个命名空间中的变量。这一点一定要注意。  

5、使用注意事项:

using namespace std 放在:#include<iostream>
                                                             using namespace std
                                                             int main()
                                                           {
                                                                  `` ````````
                                                            }
与放在:#include<iostream>
                  int main()
                {
                   using namespace std;
                    ·······················
                    ·····················
                 }
的区别:

第一种是整个文件中都引入了std命名空间,第二种则是只在main函数中引入std命名空间。
如果为了贪图方便,直接用第一种写法也行,但是C++ Primer中建议用第二种写法,这样可以防止命名空间污染(在你不想引入它的地方也被引入了,就可能导致一些问题。)

另外无论如何,都不应该把using namspace 这种语句写在头文件中,很容易出问题的。
在函数内部写using namspace其影响只限于这个函数内部,其它函数仍然没有引入这个命名空间。

不过如果你在一个文件中引入了多个命名空间的话,建议还是用第二种,它的作用范围比较有限,这样可以尽可能减小命名空间冲突的情况。任何情况下都不应在.h头文件中写using namespace xxx,而应该在定义时直接用全称,否则包含你头文件的人可能莫名其妙意外的引入了他并不想要的命名空间而出现问题。