C++命名空间namespace的使用规范

1.命名空间

namespacens

{

………//将内容添加到命名空间中

}


using namespace ns;

……..//声明命名空间后,表示ns命名空间里面的内容对于这条声明后的代码是可见的。


但是如果声明了两个命名空间ns1,ns2。且ns1和ns2中包含相同的全局变量,或函数或类,那么就可能会产生冲突。

using namespace ns1;

using namespace ns2;

………//若使用了ns1和ns2中相同部分会产生冲突。

解决方法:指定命名空间。例:ns1::变量名


2.匿名命名空间

namespace

{

…//这部分内容让该文件内所有内容可见,但仅仅能让该文件中内容可见,使用时无需作用域操作符前缀。

}

 

       在引入标准 C++名字空间之前,解决此类声明局部化问题的常见方案是使用从 C语言中继承来的关键字 static,未命名名字空间的成员与被声明为static 的全局实体具有类似的特性 。

3.命名空间污染

原则:尽量不要在头文件中出现“using namespace XXX”

原因:using namespace写在头文件的开头会将命名空间的所有内容无一例外的引入目前的命名空间中。请注意我说的“所有内容”,并不是一两个你想用的类\类型\模板。也就是说不可避免的引入了一些你所不知道的类\类型\模板。那么这会有什么影响呢?

下面举个例子:

#include<iostream>
#include<algorithm>
using namespace std;

double max(double v1,double v2)
{
    cout<<"this is my max!"<<endl;
}

int main()
{
    max(1,1);
    cout<<max(1,1)<<endl;

    return 0;
}

结果是:1

      这个例子:不会输出this is my max。如果没有using namespace std;就会输出this is my max。因为标准库中的max成为了更好的匹配,所以调用了标准库的。假如你不知道标准库中有max这个函数,你可能就会出现这种情况:你写了个max,并以为调用的是自己写的版本,但根据编译器在面对重载时的匹配规则导致实际上调用了标准库的版本,而且没有任何提示,直接编译通过了。

       可能有些人会认为这种错误是可以避免的。但是你得先知道有没有才能知道是不是需要避开;而且就算用错了你都不知道是不是一定会编译错还是直接用了你不想要的东西。尤其是当接口的实现不是自己写的时候。其实是有一般的检查是不是存在声明的自动化检查方法,但很麻烦,怎么想都是直接扔掉using namespace省事。现在想想编码时候多花个几分钟写几个std::,可能省下来将来改bug,调试时会花费的几天时间!

       如果你非常明确的想在一个头文件中使用using声明,应该怎么做?我们有其他途径可以减少不得不用using声明的情况——你可以用以下其中一种,或则多种方式的组合。

       首先,你只需使用typedef。这是应该是一个首选的方法。实际上,使用typedef有两个好处——他让一个类型名可读性增加,如果你选择了一个很好的名字,它可以让作者的意图更加显而易见。比较一下如下的声明方式:
std::map<std::string, long> clientLocations;
typedef std::map<std::string, long> ClientNameToZip;
ClientNameToZip clientLocations;

      第二个声明——即使它被展开为两行——也比第一个声明更加直观,同时,它也避免了命名空间模糊化。

      另外一个选择则是用两种方法来限制using声明的作用域——仅仅是你想用的那个“using”符号,例如:

using std::string;

      但是,把这段声明扔到头文件中,几乎和使用“using namespace”一样糟糕,因此,你应该使用作用域来限制下它的可见性,来确保你的using声明真的只在第一次做using声明的地方有效。例如,你可以用如下方法限制类声明作用域:

namespace bar
{
  struct zzz
  {
    …
  };
}
class foo
{
  using namespace bar;
  zzz m_snooze; // Pulls in bar::zzz 
};

     或者,你可以直接把using的作用域限制到一个函数中,例如:

void temp()
{
  using namespace std;
  string test = "fooBar";
}

      不管哪种方法,你都可以把using的作用域限制到需要使用它的代码中,而不是把它放到代码的公共空间中。你的工程越大,确保模块化,和最小化不可预料的负面影响就显得越发重要。


参考:http://www.ituring.com.cn/article/23606?utm_source=tuicool#

            http://tieba.baidu.com/p/4439486117



  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值