namespace名字空间小解

一、标准名字空间的理解:

      using namespace std;就是标准名字空间的引用,std是C++标准库中的名字空间名称。大家都知道,当我们定义了一个类,而声明对象的时候就要用到 class_name 后跟对象名称,标准名字空间也是这个用法。

       其实,我们可以按照一个更为抽象包含更广的类来理解标准名字空间。#include<iostream>中的iostream正是包含在这个标准名字空间里面的一个“对象”。

         namespace是为了解决C++中的名字冲突而引入的。什么是名字冲突呢?比如,在文件x.h中有个类MyClass, 在文件y.h中也有个类MyClass,而在文件z.cpp中要同时引用x.h和y.h文件。显然,按通常的方法是行不能的,那怎么办呢?引入namespace即可。


标准名字空间的用法:


我们完全可以定义自己的标准名字空间,如下例:


在x.h中的内容为  
//  x.h  
namespace  MyNamespace1  
{  
   class  MyClass  
   {  
   public:  
       void  f();  
   private:  
       int  m;  
   };  
};  


在y.h中的内容为  
//  y.h  
namespace  MyNamespace2  
{  
   class  MyClass  
   {  
   public:  
       void  f();  
   private:  
       int  m;  
   } ;
};  
然后在z.cpp中引入x.h和y.h  
//  z.cpp  
#include  "x.h"    
#include  "y.h"
using namespace MyNamespace1;
using namespace MyNamespace2;  


void  main()  
{  
   //声明一个文件x.h中类MyClass的实例x  
   MyNamespace1::MyClass  x;  
     //声明一个文件x.h中类MyClass的实例x  
   MyNamespace2::MyClass  y;  


   //调用文件x.h中的函数f  
   x.f();  
   //调用文件y.h中的函数f  
   y.f();  
}  

       名字空间实质上是一个作用域。前面所述,数据成员要包含在类里面,那么做为一个作用域更大的类,要声明的话,根据需要,一般的类就可以放到标准名字空间里面。

       那么,当我们声明了一个自己的标准名字空间之后,是否还可以添加包含更多的类呢?

       答案是肯定的,当我们需要的时候,我们还可以按照原来的格式添加,这样,再引用的时候,在定义的标准名字空间里面就包含了所有添加的类。

 二、 关于名字空间定义
    全局实体(global entity)
    全局名字空间污染(global namespace pollution)

1、名字空间定义
    namespace 开头,后面是名字空间的名字。

    namespace cplusplus_primer {
     class matrix {/*****/};
     void inverse(matrix &);
     matrix operator+(const matrix &m1,matrix &m2)
     {
      /******/
     }
     const double pi = 3.1416;
   
    }


    在名字空间cplusplus_primer中声明的类的名字是
    cplusplus_primer::matrix
    函数的名字是
    cplusplus_primer::inverse()
    常量的名字是
    cplusplus_primer::pi

    类,函数,常量被声明它的名字空间的名字限定修饰:
    这些名字被成为限定修饰符(qualified name)


    名字空间的定义不一定是连续的.例如
    namespace cplusplus_primer{
    class  matrix {/*****/}
    const double pi = 3.1416;

    }

    namespace cplusplus_primer{
    void inverse(matrix &);
    matrix operator+ (const matrix &m1,const matrix &m2)
        {/********/}
    }

    名字空间的定义可是非连续的,这对生成一个库很有帮助,它使我们更容易将库的源代码组织成
    接口和实现部分。

2、域操作符
     ::
     用户声明的名字空间成员名自动被加上前缀,名字空间名后面加上域操作符(::),名字空间成员名
     由该名字空间名进行限定修饰。

     名字空间成员的声明被隐藏在其名字空间中,除非我们为编译器指定查找的声明的名字空间,否则
     编译器将在当前域及嵌套包含当前域的域中查找该名字的声明。

     注意!!!
     域操作符也可以被用来引用全局名字空间的成员。因为全局名字空间没有名字。
     ::member_name
     指的是全局名字空间的成员。

     #include <iostream>
     const int max = 65000;
     const int lineLength = 12;

     void fibonacci(int max)
     {
        if (max <2) return;
 cout << "0 1";
 int v1 = 0,v2=1,cur;
 for (int ix=3;ix <= max;++ix)
 {
     cur = v1+v2;
     if(cur>::max) break;   //引用全局名字空间的变量;
     cout << cur <<"";
     v1=v2;
     v2=cur;
     if(ix % lineLength ==0) cout << endl;
 }
     }

3 、嵌套名字空间
     
      。。。。。


4 使用名字空间成员

     使用限定修饰的名字形式namespace_name::member_name来引用名字空间,毫无疑问是非常麻烦的。

     using 声明,using指示符

5 名字空间别名
    
     namespace International_Business_Machines
     {/*********/}

     namespace IBM = International_Business_Machines;

6、 using声明
   
    
      namespace cplusplus_primer
      {
        namespace MatrixLib
        {
         class matrix {/******/};
        }
      }

      
      using cplusplus::MatrixLib::matrix;
     

 

      using 声明引入的名字有以下特性:
       1> 它在该域中必须唯一。
       2> 由外围域中声明引入的相同名字被其隐藏。
       3> 它被嵌套域中的相同名字的声明隐藏。


       namespace blip {
        int bi = 16,bj = 15, bk = 23;

       }

       int bj = 0;

       void mainip()
       {
         using blip::bi;    //函数mainip()中的bi指向blip::bi
  ++bi;              //设置blip::bi为17
  using blip::bj     //隐藏全局域中的bj
  ++bj;
  int bk;            //bk在局部域中声明
  using blip:bk;     //错误:在mainip()中重复定义bk


       }

       int wrongInit = bk; //错误:bk在这里不可见


7、 using 指示符


       namespace blip{
       int bi = 16,bj = 15, bk = 23;
       }

       int bj = 0;

       void mainip()
       {
         using namespace blip;

  ++bi;       //设置blip::bi为17;
  ++bj;        //错误:二义性
                 全局bj还是blip:bj?

         ++::bj;     // 设置全局bj为1  
  ++blip::bj; // 设置blip::bj为16
  int bk = 97; //局部bk隐藏blip:bk
  ++bk;        //设置局部bk为98

      
       }

 

当我们把一个应用程序移植到一个包装在名字空间中的新版本时,using指示符非常
有用,但是使用多个using指示符会引起全局名字空间污染问题。
用多个选择性的using声明来代替using指示符会使这个问题最小化,由多个using
声明引起的二义性的错误在声明点就能被检测到,因此建议使用using声明而不是
using指示符,以便更好地控制程序中地全局名字空间污染问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值