父子名字空间中:
小作用域(子命名空间)会隐藏大作用域(父命名空间),无法在子命名空间和父命名空间构成重载。
但是可以在子命名空间引入父命名空间函数与子命名空间形成重载。
如下
void fun()
{
}
namespace a
{
void fun(int x)
{
}
namespace b
{
void fun(int x,int y)
{
}
void test()
{
fun();//报错
::fun();//正确
fun(1);//报错
a::fun(1);//正确
fun(1,3);//正确
}
}
}
int main()
{
a::b::test();
return 0;
}
即不同名字空间的签名相同的函数只有在引入到相同的作用域后,才可以形成重载。
如下:
代码快快1:
#include <cstdio>
void fun(int x)
{
printf("g int\n");
}
namespace y
{
void fun(int x)
{
printf("int\n");
}
}
int main()
{
fun(1);//g int
::fun(1);//g int//未引入y的fun均使用全局的fun
getchar();
}
命名空间具有隐藏功能。将使得该空间内的成员在声明该名字空间的作用域不可见。见代码块1
代码快快2:
#include <cstdio>
namespace y
{
void fun(int x)
{
printf("int\n");
}
}
int main()
{
using namespace y;//名字空间指令引入,当前作用域可见,定义在全局
fun(1);
getchar();
}
如果要使其可见,可以通过名字空间指令using namespace xx使得xx在使用该指令的作用域内具有可见性,可以在引入指令下方的代码块使用该空间内的成员。但其作用域依然属于该名字空间定义所在作用域。见代码块2
代码快快3:
#include <cstdio>
void fun(int x)
{
printf("g int\n");
}
namespace y
{
void fun(int x)
{
printf("int\n");
}
}
int main()
{
using namespace y;//名字空间指令引入到全局作用域
//fun(1);//重载全局作用域的fun(int)冲突
::fun(1);
y::fun(1);
getchar();
}
名字空间指令using namespace xx使得该名字空间内的成员在使用using namespace xx后的代码块具有可见性。如果该名字空间所在作用域中存在相同签名的函数,则只引入名字空间(引入该函数)不会发生冲突,但是一旦使用该函数,则会发生冲突。见代码块3
代码快快4:
#include <cstdio>
namespace x
{
void fun(void)
{
printf("void\n");
}
}
namespace y
{
void fun(int x)
{
printf("int\n");
}
}
int main()
{
using namespace x;
using namespace y;//名字空间指令引入到全局作用域
fun();
fun(1);//正常重载全局作用域的x::fun(void),y内的fun(int)
getchar();
}
名字空间内成员的重载,需要名字空间内的成员引入到相同的作用域。见代码块4,main中使用名字空间指令后,在该指令以下代码块,x,和y中的fun均可见,且属于全局作用域,正常形成重载。
代码快快5:
#include <cstdio>
void fun(int x)
{
printf("g int\n");
}
namespace x
{
void fun(void)
{
printf("void\n");
}
}
namespace y
{
void fun(int x)
{
printf("int\n");
}
}
int main()
{
using namespace x;
using namespace y;//名字空间指令引入到全局作用域
fun();
fun(1);//冲突,因为该位置全局fun(int)和y::fun(int)都可见
getchar();
}
1>e:\qt\test\test\test.cpp(27): error C2668: “fun”: 对重载函数的调用不明确
1> e:\qt\test\test\test.cpp(3): 可能是“void fun(int)”
1> e:\qt\test\test\test.cpp(17): 或 “void y::fun(int)”
1> 尝试匹配参数列表“(int)”时
继4此时如果全局又存在相同签名的函数,则同3,发生冲突,全局的fun和y中的fun在名字空间指令以下代码块都可见,都属于全局,且签名相同,冲突。见代码块5
代码快快6:
#include <cstdio>
void fun(int x)
{
printf("g int\n");
}
namespace x
{
void fun(void)
{
printf("void\n");
}
}
namespace y
{
void fun(int x)
{
printf("int\n");
}
}
int main()
{
using namespace x;
using namespace y;//名字空间指令将x,y的成员引入到全局作用域
fun();
y::fun(1);
::fun(1);
using x::fun;//将x::fun引入到当前局部作用域
//fun(1);//error C2660: “x::fun”: 函数不接受 1 个参数,即该局部作用域内只有x::fun(void)被引入
fun();
getchar();
}
可以通过名字空间声明将该名字空间内的成员引入当前局部作用域,由于小作用域隐藏大作用域,则只有引入到该局部作用域的可见。见代码块6,全局的将被隐藏,导致fun(1)找不到定义。
总结:
名字空间引入指令:
using namespace xx;
将名字空间内的所有成员释放到其定义坐在作用域。
名字空间成员声明:
using xx::yy;
将名字空间内的单个成员释放到当前局部作用域。
名字空间内成员函数重载条件:
首先要将成员释放(具有可见性)到相同作用域。