随笔-144  评论-80  文章-1  trackbacks-0

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

8.5.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)
        {/********/}
    }

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

 8.5.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;
 }
     }

8.5.3 嵌套名字空间
     
      。。。。。


8.6 使用名字空间成员

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

     using 声明,using指示符

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

     namespace IBM = International_Business_Machines;

8.6.2 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在这里不可见


8.6.3 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指示符,以便更好地控制程序中地全局名字空间污染问题。
      

 


 

posted on 2005-07-11 13:24 小力力力 阅读(2365) 评论(1)  编辑  收藏 所属分类: C/C++

评论:
# re: c++ primer 笔记(名字空间) 2008-07-19 03:32 | asdwq
awdqwdq  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: