C++ 命名空间

一、C++命名空间定义

一个中大型软件往往由多名程序员共同开发,会使用大量的变量和函数,不可避免地会出现变量或函数的命名冲突。当所有人的代码都测试通过,没有问题时,将它们结合到一起就有可能会出现命名冲突。

例如小李和小韩都参与了一个文件管理系统的开发,它们都定义了一个全局变量 fp,用来指明当前打开的文件,将他们的代码整合在一起编译时,很明显编译器会提示 fp 重复定义(Redefinition)错误。

为了解决合作开发时的命名冲突问题,C++ 引入了命名空间(Namespace)的概念。

二、命名空间的使用

(1)最简单的办法,在变量和函数前面加上命名空间的完整前缀:

#include <iostream>
using namespace std;
namespace nameA{
    namespace nameB{
        class NT{
        public:
            NT()
            {
                cout<<"this is my NT"<<endl;
            }
        };
    }
}

int main(){
    nameA::nameB::NT nt;
}

运行结果:

this is my NT

(2)也可以使用using namespace ×××

#include <iostream>
using namespace std;
namespace nameA{
    namespace nameB{
        class NT{
        public:
            NT()
            {
                cout<<"this is my NT"<<endl;
            }
        };
    }
}
int main(){
    using namespace nameA::nameB;
    NT nt;
}

(3)你甚至可以使用using namespace+前缀组合的方式,处理嵌套的命名空间。

#include <iostream>
using namespace std;
namespace nameA{
    namespace nameB{
        class NT{
        public:
            NT()
            {
                cout<<"this is my NT"<<endl;
            }
        };
    }
}
int main(){
    using namespace nameA;
    nameB::NT nt;
}

三、using namespace+前缀组合规则
一句话,前缀是编译器必须的考虑的,using namespace是编译器选择参考的。
加上using namespace后,编译器会尝试给前缀前面加上相应的修饰,但是也会到不加修饰的空间里面寻找,能且只能找到一个!

#include <iostream>
using namespace std;
namespace nameA{
    namespace nameB{
        class NT {
        public:
            NT()
            {
                cout<<"this is my NT"<<endl;
            }
        };
    }
}
int i=0;
int main(){
    using namespace nameA;
    nameA::nameB::NT nt1; 
    nameB::NT nt2;
    i++;
}

行为如下:
(1)尝试在nameA::nameA::nameB中找到NT类,找不到这个命名空间,终止。
(2)尝试在nameA::nameB中找到NT类,找到了,结束。
(3)尝试在nameA::nameB中找到NT类,定义nt2,找到了,结束。
(4)尝试在nameB命名空间中寻找,没有这个命名空间,结束。
(5)在nameA中找变量i,找不到,结束。
(6)在全局命名空间中找i,找到了。
有一个隐含过程,因为在最开始using namespace std,所以会在std空间里面找东西。

四、using namespace 的优先级。
using namespace可以声明在很多地方,可以在函数中,也可以在函数外,但是只要代码处于using namespace的作用域中,**各个using namespace就没有优先级!!!**所以要避免二义性报错。
(1)命名空间二义性
让编译器知道使用哪一个命名空间。

#include <iostream>
using namespace std;
namespace nameA{
    namespace nameB{
        class NT {
        public:
            NT()
            {
                cout<<"this is my NT"<<endl;
            }
        };
    }
}

namespace nameB{
   int i;
}

int main(){
    using namespace nameA;
    nameA::nameB::NT nt1;
    nameB::NT;  //报错,编译器不知道是哪一个命名空间。
}

编译器既可以使用命名空间nameB,又可以使用命名空间nameA::nameB,二者没有优先级,报错。

(2)命名空间中的成员歧义:

#include <iostream>
using namespace std;
namespace nameA{
    namespace nameB{
        class string {
        public:
            string()
            {
                cout<<"this is my string"<<endl;
            }
        };
    }
}

int main(){
    using namespace nameA::nameB;
    string str; //报错,编译器不知道是标准库string还是自定义string
}

由于最开始using namespace std,编译器也会尝试在std中寻找string,也会在nameA::nameB中寻找string,二者没有优先级,歧义报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值