您的位置:首页 > 编程语言 > C语言/C++

C++不同名字空间的函数重载解析

2018-03-03 17:55 309 查看
父子名字空间中:

小作用域(子命名空间)会隐藏大作用域(父命名空间),无法在子命名空间和父命名空间构成重载。

但是可以在子命名空间引入父命名空间函数与子命名空间形成重载。

如下

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;

将名字空间内的单个成员释放到当前局部作用域。

名字空间内成员函数重载条件:

首先要将成员释放(具有可见性)到相同作用域。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 namespace