C++的命名空间

命名空间

命名空间的主要作用是解决命名冲突,以区分名称相同的两个变量或方法。类似于区分3班的张伟和7班的张伟,或3班的班规和7班的班规。

作用域符号"::"

说到命名空间的使用,不得不先提的一个符号"::"。

用法: 命名空间名称::变量名,命名空间名称::方法名()。

若无命名空间名称,直接写 ::a ,那么就是使用的全局变量

如果有两个同名的变量a,一个是全局变量,一个是局部变量,若无指定说明,按照就近原则,局部变量优先于全局变量。若要使用全局变量,则要在变量前加上"::"。 

#include <iostream>
using namespace std;

int a=10;//全局变量
void func()
{
    int a=100;//局部变量
    cout<<"局部变量 a="<<a<<endl;
    cout<<"全局变量 a="<<::a<<endl;

}

int main(int argc, char *argv[])
{
    func();
    return 0;
}

 运行结果

命名空间定义

命名空间定义用关键字 namespace 来定义。

#include <iostream>
using namespace std;

int a=10;//全局变量
//定义命名空间
namespace AA{
    int a= 102 ;
}
namespace BB{
    int a =1002 ;
}

int main(int argc, char *argv[])
{
    int a=100;//局部变量
    cout<<"局部变量 a="<<a<<endl;
    cout<<"全局变量 a="<<::a<<endl;
    cout<<"AA空间   a="<<AA::a<<endl;
    cout<<"BB空间   a="<<BB::a<<endl;
    return 0;
}

运行结果:

命名空间必须在全局范围内定义,否则编译会出错。

#include <iostream>
using namespace std;

int a=10;//全局变量
//定义命名空间
namespace AA{
    int a= 102 ;
}

void func()
{
    //非法的 命名空间BB
    namespace BB{
        int a =1002 ;
    }
    cout<<"AA空间 a="<<AA::a<<endl;
    cout<<"BB空间 a="<<BB::a<<endl;
}
int main(int argc, char *argv[])
{
    func();
    return 0;
}

编译结果:命名空间不允许定义在这里,且BB未被声明。

命名空间可以嵌套定义,BB空间生命在AA空间中。

#include <iostream>
using namespace std;

int a=10;//全局变量
//定义命名空间
namespace AA{
    int a= 102 ;
    namespace BB{
        int a =1002 ;
    }
}

int main(int argc, char *argv[])
{
    int a=100;//局部变量
    cout<<"局部变量 a="<<a<<endl;
    cout<<"全局变量 a="<<::a<<endl;
    cout<<"AA空间 a="<<AA::a<<endl;
    cout<<"BB空间 a="<<AA::BB::a<<endl;
    return 0;
}

运行结果:

 命名空间的开放性

 命名空间成员变量和函数可以随时增加,只需要在namespace中声明即可。

调用时需声明变量及函数归属的命名空间。命名空间内可直接调用,不必声明空间名称。

#include <iostream>
using namespace std;

//定义命名空间
namespace AA{
    int a = 102 ;
    int b = 103 ;
}

//AA空间的扩展定义新成员
namespace AA{
    int c=1001;
    void plus(){
        cout<<"This is function plus(),c="<< c <<endl;
    }
    void sub();
}

int main(int argc, char *argv[])
{
    cout<<"AA空间 a="<<AA::a<<endl;
    cout<<"AA空间 b="<<AA::b<<endl;
    cout<<"AA空间 c="<<AA::c<<endl;
    AA::plus();
    return 0;
}

运行结果

外部定义函数

命名空间中的函数可以在外部定义,但是一定要在内部声明。

在外部定义时,要表明其归属的命名空间。

#include <iostream>
using namespace std;

//定义命名空间
namespace AA{
    int a = 102 ;
    int b = 103 ;
}

//AA空间的扩展定义新成员
namespace AA{
    int c=1001;
    int d=2001;
    void plus(){
        cout<<"This is function plus(),c="<< c <<endl;
        }
    void sub();
}
//外部定义
void AA::sub(){
    cout<<"This is function plus(),d="<< d <<endl;
}

int main(int argc, char *argv[])
{
    cout<<"AA空间 a="<<AA::a<<endl;
    cout<<"AA空间 b="<<AA::b<<endl;
    cout<<"AA空间 c="<<AA::c<<endl;
    AA::plus();
    AA::sub();
    return 0;
}

 运行结果

 无名命名空间

表明此空间内的标识符只能在本文件内访问,相当于给标识符加上static。

尽量避免此类用法,以免造成歧义。

#include <iostream>
using namespace std;

//定义命名空间
namespace AA{
    int a = 102 ;
    int b = 103 ;
}

//无名的命名空间
namespace{
    int n=3001 ;
}
int main(int argc, char *argv[])
{
    cout<<"AA空间 a="<<AA::a<<endl;
    cout<<"AA空间 b="<<AA::b<<endl;
    cout<<"无名空间 n="<< n <<endl;
    return 0;
}

 运行结果

 命名空间的别名

定义别名用namespace。用法可以理解为赋值,把原有的空间名称,赋值给新的空间名称。

意义:每次调用时不用写很长的空间前缀。

#include <iostream>
#include <file.cpp>
using namespace std;

//定义命名空间
namespace veryLongName{
    int a = 102 ;
    int b = 103 ;
}

int main(int argc, char *argv[])
{
    namespace shortName = veryLongName;//为veryLongName起别名为shortName
    cout<<"空间别名shortName调用 a="<<shortName::a<<endl;
    cout<<"空间别名shortName调用 b="<<shortName::b<<endl;
    return 0;
}

运行结果 

 using的使用

using是简化了命名空间的成员访问。使用频次高的空间成员更快捷的调用,不用每次调用都写一遍空间名称。

如果要调用其他命名空间的成员,还是要写上空间名称的。

#include <iostream>
using namespace std;

//定义命名空间
namespace AA{
    int a = 102 ;
    void func()
    {
        cout<<"这是AA的func()函数"<<endl;
    }
}
namespace BB {
    int b = 103 ;
}
void func(){
    cout<<"这是普通函数func"<<endl;
}

int main(int argc, char *argv[])
{
    using namespace AA ; //声明从此位置往下执行的语句优先使用AA空间的成员
    int b = 100 ;
    cout<<"AA空间 调用 a="<< a <<endl;
    cout<<"优先调用局部变量 b="<< b <<endl;
    cout<<"BB空间 调用 b="<<BB::b <<endl;
    return 0;
}

运行结果

当然,在享受便捷的同时,也是有代价的,代价是容易造成冲突。

如普通函数与成员函数与命名空间中的成员函数冲突,即使声明了using namespace 也会编译出错。因为这两个函数都被认为是全局函数方法。

#include <iostream>
using namespace std;

//定义命名空间
namespace AA{
    int a = 102 ;
    void func()
    {
        cout<<"这是AA的func()函数"<<endl;
    }
}
void func(){
    cout<<"这是普通函数func"<<endl;
}

int main(int argc, char *argv[])
{
    using namespace AA ; 
    func();
    return 0;
}

 编译结果

 

解决冲突的方法,就需要表明要调用的具体是哪个函数。使用关键字using,此时就只能调用指定的成员,其他成员则无法访问。

如下代码中,指定使用AA的func,那么命名空间中只有func()可以被访问,变量a不可被访问。变量a 会从其他地方寻找(局部变量、全局变量等)。

#include <iostream>
using namespace std;

//定义命名空间
namespace AA{
    int a = 102 ;
    void func()
    {
        cout<<"这是AA的func()函数"<<endl;
    }
}
void func(){
    cout<<"这是普通函数func"<<endl;
}
int a = 1000;
int main(int argc, char *argv[])
{
    using AA::func;
    func();
    cout<<"a="<< a <<endl;
    return 0;
}

运行结果

using直接使用命名空间中的成员会和局部变量冲突,编译会报错,提示变量已经声明过。不会和全局变量冲突,因为全局变量可以被看成 ::a

所以要尽量避免这种情况的发生。

#include <iostream>
using namespace std;

//定义命名空间
namespace AA{
    int a = 102 ;
}

int main(int argc, char *argv[])
{
    int a = 2000;
    using AA::a;
    cout<<"变量 a="<< a <<endl;
    return 0;
}

编译结果

解决空间成员间的二义性,就必须加作用域名称。

#include <iostream>
using namespace std;

//定义命名空间
namespace AA{
    int a = 102 ;
}
namespace BB{
    int a = 202 ;
}
int main(int argc, char *argv[])
{
    using namespace AA;
    using namespace BB;
    cout<<"AA变量 a="<< AA::a <<endl;
    cout<<"BB变量 a="<< BB::a <<endl;
    return 0;
}

运行结果

否则编译会出错。

编译结果

 总结

命名空间的定义,不能在函数内定义。

使用命名空间的成员,最准确最安全的方式 是 命名空间名称::成员名,函数不带()。

使用整个命名空间,using namespace 命名空间名称(常用)。

使用命名空间指定成员,using 命名空间名称::成员名(不常用),容易和局部变量冲突。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值