1.内存名字隐藏外层名字
2.嵌套名字空间逐层分解
3.名字空间别名定义方法:namespace ns = 名字空间;
如:
namespace ns1{
typedef int TYPE;
namespace ns2{
typedef int* TYPE;
namespace ns3{
typedef string TYPE;
namespace ns4{
typedef string* TYPE;
}
}
}
}
using namespace ns1;
TYPE n = 10;
cout << n << endl;
ns1::ns2::TYPE pn = &n;
cout << *pn << endl;
ns1::ns2::ns3::TYPE str ("hello");
cout << str << endl;
ns1::ns2::ns3::ns4::TYPE pstr1 = &str;
cout << *pstr1 << endl;
namespace ns_four = ns1::ns2::ns3::ns4;
ns_four::TYPE pstr2 = pstr1;
cout << *pstr2 << endl;
结果上面:都能输出相应的值
4.不同名字空间中的成员使用:
namespace ns1
{
class A
{
};
void foo (A a)
{
cout << "ns1::foo() invoked" << endl;
}
}
namespace ns2
{
void foo (ns1::A a)
{
cout << "ns2::foo() invoked" << endl;
}
}
ns1::A a;
ns1::foo(a);
ns2::foo(a);
结果:
ns1::foo() invoked
ns2::foo() invoked
另外: 在当前作用域内声明的名字(无论是直接声明还是通过using声明)一定会隐藏其可见名字空间中声明的名字,即使using指令在using声明之后。
using ns1::foo; /*将ns1名字空间中的foo()引入当前作用域,覆盖所有可见名字空间中的foo(),通过using声明在当前作用域中声明了一个特定的名字之后,
如果程序试图声明另一个相同的名字,将导致编译时错误,如:using ns2::foo; // 编译时错误,名字冲突*/
foo (a);
using namespace ns2;//using指令说明这些名字空间中的名字在当前作用域中可见,但并没有将这些名字空间中的名字引入当前作用域。
如果引入了,就会隐藏其他的,也就无歧义;但是如果只是可见,那么就可能产生歧义
using指令只是说明在当前作用域中这些定义的名字可以直接使用(要求没有歧义)
foo (a); // 调用ns1名字空间中的foo(),ns2名字空间中的foo()被ns1名字空间中的foo()隐藏
5.只有同一作用域中的同名函数才会涉及重载的问题,不同作用域中的同名函数遵循标示符隐藏原则。
6.无名作用域中声明的名字可以直接使用,或者需要作用域时使用全局作用域::
namespace{//无名作用域
void foo (void){
cout << "::foo() invoked" << endl;
}
}
7.名字空间具有传递性:
namespace ns1{
void foo (void){
cout << "ns1::foo() invoked" << endl;
}
}
namespace ns2{
void foo (void){
cout << "ns2::foo() invoked" << endl;
}
}
namespace ns3{
using namespace ns1; // ns3可见ns1中的foo()
using namespace ns2; // ns3可见ns2中的foo()
void foo (void){
cout << "ns3::foo() invoked" << endl;
}
}
using namespace ns3; // 当前作用域可见ns3中的foo(),同时亦可见ns1和ns2中的foo()
//foo (); // 编译时错误,歧义
//但是在当前作用域又可以隐藏其他的名字:
ns3::foo (); // 在ns3的作用域中,ns1和ns2中的foo()已被其自己的foo()所隐藏,故无歧义
//如果ns3中没有定义foo那么就会调用其他的名字空间中的foo(当然要求其他的包含名字空间之间没有歧义)
8.不能用::来引入新的成员名字
但是可以再定义同样的名字空间添加这些成员名字,编译器会组合这些名字空间,但是不能重复
9.函数声明和标示符隐藏原则:
void func (int n){
cout << "func(int) invoked" << endl;
}
void func (char c){
cout << "func(char) invoked" << endl;
}
func (10); // 匹配到void func (int n)版本
//声明
void func (char c); // 后声明的标识符隐藏先声明的同名标识符
func (10); // 匹配到void func (char c)版本