C++命名空间(namespace)

c++中,名称(name)能够是符号常量、变量、函数、结构、枚举、类和对象等等。工程越大,名称互相冲突性的可能性越大。另外使用多个厂商的类库时,也可能致使名称冲突。为了不,在大规模程序的设计中,以及在程序员使用各类各样的C++库时,这些标识符的命名发生冲突,标准C++引入关键字namespace(命名空间/名字空间/名称空间),能够更好地控制标识符的做用域。c++

 

建立一个命名空间:程序员

namespace A{ int a = 10; } namespace B{ int a = 20; } void test(){ cout << "A::a : " << A::a << endl; cout << "B::a : " << B::a << endl; }

 

命名空间只能全局范围内定义(如下错误写法函数

void test(){ namespace A{ int a = 10; } namespace B{ int a = 20; } cout << "A::a : " << A::a << endl; cout << "B::a : " << B::a << endl; }

 

命名空间可嵌套命名空间spa

namespace A{ int a = 10; namespace B{ int a = 20; } } void test(){ cout << "A::a : " << A::a << endl; cout << "A::B::a : " << A::B::a << endl; }

 

命名空间是开放的,便可以随时把新的成员加入已有的命名空间中设计

namespace A{ int a = 10; } namespace A{ void func(){ cout << "hello namespace!" << endl; } } void test(){ cout << "A::a : " << A::a << endl; A::func(); }

 

声明和实现可分离code

 

#pragma once

namespace MySpace{ void func1(); void func2(int param); }

 

void MySpace::func1(){ cout << "MySpace::func1" << endl; } void MySpace::func2(int param){ cout << "MySpace::func2 : " << param << endl; }

 

无名命名空间,意味着命名空间中的标识符只能在本文件内访问,至关于给这个标识符加上了static,使得其能够做为内部链接对象

namespace{ int a = 10; void func(){ cout << "hello namespace" << endl; } } void test(){ cout << "a : " << a << endl; func(); }

 

命名空间别名blog

namespace veryLongName{ int a = 10; void func(){ cout << "hello namespace" << endl; } } void test(){ namespace shortName = veryLongName; cout << "veryLongName::a : " << shortName::a << endl; veryLongName::func(); shortName::func(); }

 

------------------------------------------------------------------------------------------------------------------------------------------------------------作用域

using声明编译

using声明可以使得指定的标识符可用。

namespace A{ int paramA = 20; int paramB = 30; void funcA(){ cout << "hello funcA" << endl; } void funcB(){ cout << "hello funcA" << endl; } } void test(){ //1. 经过命名空间域运算符
    cout << A::paramA << endl; A::funcA(); //2. using声明
    using A::paramA; using A::funcA; cout << paramA << endl; //cout << paramB << endl; //不可直接访问
 funcA(); //3. 同名冲突 //int paramA = 20; //相同做用域注意同名冲突
}

using声明碰到函数重载     

若是命名空间包含一组用相同名字重载的函数,using声明就声明了这个重载函数的全部集合。

 1 namespace A{  2     void func(){}  3     void func(int x){}  4     int  func(int x,int y){return x+y;}  5 }  6 void test(){  7     using A::func;  8  func();  9     func(10); 10     func(10, 20); 11 }

 --------------------------------------------------------------------------------------------------------------

using编译指令

 

using编译指令使整个命名空间标识符可用.

 注意:使用using声明或using编译指令会增长命名冲突的可能性。也就是说,若是有名称空间,并在代码中使用做用域解析运算符,则不会出现二义性。

namespace A{ int paramA = 20; int paramB = 30; void funcA(){ cout << "hello funcA" << endl; } void funcB(){ cout << "hello funcB" << endl; } } void test01(){ using namespace A; cout << paramA << endl; cout << paramB << endl; funcA(); funcB(); //不会产生二义性
    int paramA = 30; cout << paramA << endl; } namespace B{ int paramA = 20; int paramB = 30; void funcA(){ cout << "hello funcA" << endl; } void funcB(){ cout << "hello funcB" << endl; } } void test02(){ using namespace A; using namespace B; //二义性产生,不知道调用A仍是B的paramA //cout << paramA << endl;
}

 

 

 

命名空间使用

须要记住的关键问题是当引入一个全局的using编译指令时,就为该文件打开了该命名空间,它不会影响任何其余的文件,因此能够在每个实现文件中调整对命名空间的控制。好比,若是发现某一个实现文件中有太多的using指令而产生的命名冲突,就要对该文件作个简单的改变,经过明确的限定或者using声明来消除名字冲突,这样不须要修改其余的实现文件。