C++ Namespace 详解

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

namespace 命名空间名 {              
            声明序列可选       
}

无名的命名空间:

namespace {              
            声明序列可选       
}

一、<iostream>和<iostream.h>

后缀为.h的头文件c++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,c++标准为了 和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。
  因此,当使用 <iostream.h> 时,相当于在c中调用库函数,使用的是全局命名空间,也就是早期的c++实现;当使用 <iostream> 的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。

  • <string.h> 是旧的C头文件,对应的是基于char*的字符串处理函数;
  • <string> 是包装了std的C++头文件,对应的是新的strng类;
  • <cstring> 是对应旧的C头文件的std版本。

二、使用命名空间

由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:
+ 1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下: std::cout << std::hex << 3.4 << std::endl;
+ 2、使用using关键字。 using std::cout; using std::endl; 以上程序可以写成 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; 

无数原有的C++代码都依赖于使用了多年的伪标准库中的功能,他们都是在全局空间 下的。 所以就有了

#include     
using std::cin;   
using std::cout;   
using std::endl;   
template     
T max (T a,T b)   
{   
    return ((a>b)?a:b);   
} 
void main()   
{   
    double x,y;   
    cin>>x>>y;   
    cout<<"Max number is "<<(max(x,y))<<endl;
    cin>>x;   
} 

这是比较推荐的做法,因为C++ PRIMER, EFFECTIVE C++上都是用这种方式的。

测试例子

通过名空间,可以在同一个文件中使用相同的变量名或函数名,只要它们属于不同的名空间。另外,名空间可以使得代码操作具有相同名字但属于不同库的变量。而且,名空间也可以提高C语言与C++语言的兼容性。 下面通过例程说明关键字namespace的用法。

#include  <conio.h>  
#include  <iostream.h>  
namespace  car  //  名空间的定义  
{  
     int  model;  
     int  length;  
     int  width;  
}  

namespace  plane  
{  
     int  model;  
     namespace  size  //  名空间的嵌套  
     {  
         int  length;  
         int  width;  
     }  
}  

namespace  car  //  添加名空间的成员  
{  
     char  *  name;  
}  

namespace  c=car;  //  定义名空间的别名  
int  Time;  //  外部变量属于全局名空间  

void  main()  
{  
     car::length=3;  
     //  下面一句错误,故屏蔽掉  
     //  width=2;  //  对于非全局变量和当前有效临时变量应该指定名空间  
     plane::size::length=70;  
     cout<<"the  length  of  plane  is  "<<plane::size::length<<"m."<<endl;  
     cout<<"the  length  of  car  is  "<<car::length<<"m."<<endl;  
     //  使用名空间的别名  
     cout<<"the  length  of  c  is  "<<c::length<<"m."<<endl;  
     int  Time=1996;  //  临时变量,应区别于全局变量  
     ::Time=1997;  
     cout<<"Temp  Time  is  "<<Time<<endl;  
     cout<<"Outer  Time  is  "<<::Time<<endl;  
     //  使用关键字using  
     using  namespace  plane;  
     model=202;  
     size::length=93;  
     cout<<model<<endl;  
     cout<<size::length<<endl;  
     getch();  
}  

运行结果:

the  length  of  plane  is  70m.  
the  length  of  car  is  3m.  
the  length  of  c  is  3m.  
Temp  Time  is  1996  
Outer  Time  is  1997  

说明:

  • 从上面可以看出,名空间定义了一组变量和函数,它们具有相同的作用范围。对于不同的名空间,可以定义相同的变量名或函数名,在使用的时候,只要在变量名或函数名前区分开不同的名空间就可以了。
  • 名空间可以被嵌套定义,使用时要逐级对成员用名空间限定符: :来引用。
  • 系统默认有一个全局名空间,它包含了所有的外部变量。这个名空间没有名字,引用这个名空间里的变量时要使用名空间限定符: :,前面没有名字。在不使用名空间的情况下,我们知道,不可以在不同文件中定义相同名字的外部变量,这是因为它们属于同一个全局名空间,名字不可以重复。
  • 可以给名空间取一个别名。一般别名是一个比较短的名字,来简化编程。
  • 在原有定义好的名空间的基础上,随时可以往里增加成员。

如果没有名空间的干扰,函数重载时选择规则将是非常简单。只要实参是double类型,则调用的是前面的函数;如果实参是int类型,则调用后面的函数。但是由于名空间的参与,就出现了上面的运行结果。所以在编程的时候一定要注意名空间对函数重载的影响。

#include  <conio.h>  
#include  <iostream.h>  
namespace  car  //  名空间的定义  
{  
     void  ShowLength(double  len)  //  参数类型为d  o  u  b  l  e  
     {  
         cout<<"in  car  namespace:  "<<len<<endl;  
     }  
}  

namespace  plane  //  名空间的定义  
{  
     void  ShowLength(int  len)  //  参数类型为i  n  t  
     {    
         cout<<"in  plane  namespace:  "<<len<<endl;  
     }  
}  

void  main()  
{  
     using  namespace  car;  
     ShowLength(3);  
     ShowLength(3.8);  
     using  namespace  plane;  
     ShowLength(93);  
     ShowLength(93.75);  
     getch();  
}

运行结果:

in  car  namespace:  3  
in  car  namespace:  3.8  
in  plane  namespace:  93  
in  car  namespace:  93.75  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值