C++命名空间

来源:互联网 发布:linux 给用户目录权限 编辑:程序博客网 时间:2024/06/05 21:17

吐槽,书上翻译成名称空间。。。我觉得很通俗很好。。。

一、声明

/* 命名名称空间 */namespace A{    void _f(int n);}/* 未命名名称空间 */namespace{    void _f2(int n){        std::cout<<"_f2"<<std::endl;    }}

二、特点
1、命名空间特点

  • 命名空间可以是全局的,也可以位于另一个名称空间内,但不能位于代码块中
  • 命名空间是开放的,可以把名称加入到已有的名称空间中。加入之后,只有位置位于加入之后的代码才能使用新加入的名称空间名称,看定义中的代码

2、未命名名称空间
可以通过省略名称空间的名字来创建未命名的名称空间。

  • 潜在作用域为声明点到声明区域结尾。这点看,与全局变量相似
  • 不能使用using指令在其它地方使用
  • 链接性为内部的静态变量的替代品

三、定义

/* 名称空间 */namespace A{    void _f(int n){        std::cout<<"_f"<<std::endl;    }    void _f2();    void _f3();}//方法1A::_f3(){}//添加名称namespace A{    using namespace std;}//方法2,限定定义函数?namespace A{    void _f2(){        cout<<"_f2"<<endl;    }}//可以在新的.cpp文件中定义命名空间,使用using namespace A避免重复输入类似A::_f

完整定义方法:
摘自:ljq32《命名空间的定义与使用》

//17.2.A.h   头文件定义命名空间 primer_17_2  namespace primer_17_2  {    //定义成员类A    class A    {      public:        int getA(); //成员函数,定义在命名空间的定义文件中,并且在命名空间内部定义;        int getB(); //成员函数,定义在命名空间的定义文件中,但是,它是在命名空间外部定义的,请查看下边的 17.2.A.cpp 定义文件;        int fun() { return 0; } //成员函数及其实现体,在类内部定义,也就是在命名空间的头文件中定义;        friend A operator+(const A &lhs, const A &rhs); //将操作符函数声明为友元函数,因为该函数被定义成了非成员函数;      private:        int v;    };    A operator+(const A &lhs, const A &rhs); //为命名空间primer_17_2声明一个加操作符成员,必须在命名空间头文件以外定义,在命名空间实现文件中定义时:既可以在命名空间内部定义也可以在外部定义,外部定义时必须指定命名空间限定符;在其他文件中定义时:必须指定命名空间限定符,以指明函数属于哪个命名空间;    char get(); //为命名空间primer_17_2声明一个普通成员,方法同加操作符,本例中,该函数定义在了其他文件中,请看文件:17.2.C.cpp;    const char ch1 = 'a';   //ok  为命名空间primer_17_2定义一个字符常量并初始化,常量必须设置初始值;    static char ch2 = 'b';   //ok  为命名空间primer_17_2定义一个静态字符常量,并设置初始值,在使用的程序中可以修改;    static char ch3;// = 'c';    //ok  为命名空间primer_17_2定义一个字符常量,不设置初始值,在使用的程序中可以修改;    //static const char ch4;    //error, 常量必须设置初始值;    static const char ch4 = 'd';    //ok  静态的常量,设置了初始值;    extern char ch5;    //声明字符变量ch5,在使用的程序中进行定义,如:char primer_17_2::ch5,或 char primer_17_2::ch5 = 'e',必须在extern声明后,再在命名空间实现文件中定义该变量;    extern int n;    //声明定义方法同上;  } //; 这里不需要以分号结尾 

未命名空间须在空间内定义函数

四、使用
1、通过域运算符::调用,类似std::cout;
2、使用类似using namespace std; 在潜在作用域内使用std内所用名称
3、使用using std::cout;在潜在作用域内使用cout名称

五、其他使用方法
1、嵌套
使用A::B::c调用
2、全局命名空间
全局作用域中定义的名字(即在所有的类、函数以及命名空间之外定义的名字), 都会被隐式的添加到全局命名空间中。
使用::a调用
3、命名空间内联
c++中,名字空间的目的是分割全局共享的名字空间。
在c++11中,引入了“内联命名空间” inline namespace 就可以声明一个内联命名空间。
在内联空间中,允许程序员在父命名空间定义或者特化名字空间的模板。
当你需要长期维护,发布不同的版本的时候,可以用一下内联名字空间。 后续还会介绍。
在命名空间第一次被声明的地方加上inline关键字,则这个命名空间中的名字可以被外层命名空间看见,如:

namespace ns {  inline newEdition {     xxx  }  oldEdition { xx}}

这样用户在使用ns命名空间中的名字时,可以直接使用新版本的名字,如ns::newName,而非内联则需要ns::oldEdition::oldName;
通常实际的代码会这么写(再次声明#include只是简单的文本替换)

namespace ns {  inline namespace newEd { #include "newEd" }  namespace oldEd { #include "oldEd" }}

4、命名空间别名
namespace 别名 = 命名空间名;

0 0