/*
命名空间:
命名空间的定义:
namespace namespace_name{
//...类、函数变量的定义以及其他的命名空间
}
在命名空间定义的名字可以被命名空间的中其他成员直接访问,命名空间外部的代码必须指出名字定义在哪个命名空间中:
例如:
namespace_name::类/函数/变量。
也可以通过编写using声明来获得对已经直到的经常使用的名字的直接访问:
using namespace_name::类/函数/变量;
命名空间可以是不连续的:命名空间可以分散在多个文件中,但是命名空间是积累的。
接口和实现的分离:
1.定义类的命名空间成员,以及作为类接口的一部分的函数声明与对象声明,可以放在头文件中,使用命名空间成员的文件可以包含这些头文件。
2.命名空间成员的定义可以放在单独的源文件中。
嵌套的命名空间:
namespace namespace_name{
namespace namespace_name2{
//定义。。
}
//定义。
}
如果需要访问嵌套命名空间的成员,则需要指明的命名空间为:
namespace_name::namespace_name2::类/函数/变量。
未命名的命名空间:
未命名的命名空间以关键字namespace开头,接在关键字namespace后面的是由或括号定届的声明块。
1.未命名的命名空间可以在给定文件中不连续,但不能跨越文件,没个文件有自己的未命名的命名空间。
2.为命名的命名空间用于声明局部于文件的实体,在未命名的命名空间中定义的变量在程序开始时创建,在程序结束之前一直存在。
3.未命名的命名空间中定义的名字可以直接使用,因为没有命名空间名字来限定它们,不能使用作用域操作符来引用未命名的命名空间的成员。
4.未命名的命名空间的名字只在包含该命名空间的文件中可见。
5.未命名的命名空间中定义的名字可以在定义该命名空间所在的作用域中找到。如果在文件的最外层作用域中定义未命名的命名空间,那么,未命名的命名空间中的名字必须与全局作用域定义的名字不同:
int i;//全局作用域
//命名空间
namespace{
int i;
}
//下面这句代码错误。
i=10;
6.未命名的命名空间可以嵌套:
namespace local{
namespace{
int i;
}
}
//访问
local::i=10;
如果头文件定义了未命名的命名空间,那么,在每个包含该头文件的文件中,该命名空间中的名字将定义不同的局部实体。
在所有其他的方式中,未命名的命名空间的成员都是普通程序实体。
注:C++不赞成文件静态声明,不赞成的特征是在未来版本中可能不支持的特征,应该避免文件静态而使用未命名的命名空间代替。
命名空间的使用:
using声明:using namespace_name::类名/函数/变量
using声明遵循常规的作用域规则,声明命名空间的某个成员可见。
using指示:using namespace namespace_name;
using指示,将注入命名空间的所有命名,可能会发生命名空间污染。
*/
//using指示例子:
namespace blip{
int bi=11,bj=12,bk=13;
}
//与命名空间的成员同名
int bj=0;
void manip(){
//使用using指示,注入命名空间的所有名字
using namespace blip;
//直接访问命名空间的成员
++bi;
//下面这句具有二义性,将编译错误
//++bj;
//对于油二义行的变量,应该显示指出想要的哪个版本
//访问命名空间的bj
++blip::bj;
//访问命名空间外的bj
++::bj;
//定义bk,覆盖命名空间的bk
int bk=1000;
++bk;
}
int main(){
return 0;
}
/*
类、命名空间和作用域:
对命名空间内部使用的名字的查找遵循常规C++查找规则:当查找名字的时候,通过外围作用域想外查找。
当类包在命名空间的时候,发生相同的查找:受限在成员中找,然后在类(包括基类)中找,再在外围作用域中找,外围作用域中的一个或多个可以是命名空间。
实参相关的查找与类类型形参:
接受类类型形参(或类型指针及引用形参)的且与类本身定义在同一个命名空间中的函数(包括重载操作符),在用类类型对象(或类类型的引用及指针)作为实参的时候是可见的。
隐式友元声明与命名空间:
如果该友元接受类型实参并与类隐式声明在同一命名空间中,则使用它式可以无须使用显式命名空间限定符。
重载与using指示:
using指示将命名空间成员提升到外围作用域。如果命名空间函数与命名空间所在的作用域中声明的函数同名,就将命名空间成员加到重载集合中。
可以跨越多个using指示的重载。
*/
//类报在命名空间时的名字查找,例如;
#include<string>
namespace A{
int i;
int k;
class C1{
public:
//访问类成员
C1():i(0),j(0){}
int f1(){
//访问命名空间的k
return k;
}
// int f2(){
//访问未定义的命名空间的成员
// return h;
// }
int f3();
private:
int i,j;
};
//访问命名空间里的i
int h=i;
}
int A::C1::f3(){
//访问命名空间的成员。
return h;
}
//隐士友元与命名空间:
namespace A1{
class C{
//友元声明
friend void f(const C& c ){};
};
}
//如果该友元接受类型实参并与类隐式声明在同一命名空间中,则使用它式可以无须使用显式命名空间限定符。
void f2(){
A1::C cobj;
//不用声明f
f(cobj);
}
//using指示将命名空间成员提升到外围作用域。如果命名空间函数与命名空间所在的作用域中声明的函数同名,就将命名空间成员加到重载集合中。例如:
namespace libs_R_us{
extern void print(int){};
extern void print(double){};
}
void print(const std::string &test){};
//引入命名空间的成员,将有三个重载的print函数。
using namespace libs_R_us;
void fooBar(int ival){
print("xxx");
print(ival);
}
int main(){
return 0;
}