正确使用namespace(命名空间)

命名空间(namespace)在C++中的作用非同一般。本文目的不在于阐述命名空间的语法, 而在于演示命名空间的使用方法,或者说是使用命名空间的小窍门。

命名空间可以简单的将一些命名(name)用另一个命名打包封装起来。比方说:

namespace net {
  class Socket {
    ...
  };
}
...
net::Socket socket;

经过这样的封装以后,如果在两个库(library)都实现了 Socket类,只要它们命名空间的名字不同,你就可以同时使用它们而没有任何命名上的冲突 。

但这样做还是有问题:假如两个公司都要写一个network库,那么当她们编写代码的时候 都使用Socket命名他们的类的可能性有多大?我猜是接近100%。

命名空间的名字最好是方便输入的,就是说命名空间的名字最好别太长了,2-4个字符就 可以了。抱着这样的想法,那两个公司把他们的命名空间叫做net的机会又是多大呢?5%还是 10%?

不难看出,命名空间并没有解决所有问题,它只是使发生命名冲突的机会相对小了而已。

有一种叫做“工业化长度”的方法(Industrial Strength Solution),这种 方法在命名namespace的时候使用长的唯一的名称,而在程序里使用短的别名。如此network 库就可能会是这个样子:

namespace net_33843894 {
  class Socket {
    ...
  };
}

net_后面的数字是由一个随机数产生器产生的。为了以后描述方便,这里我们假定 上面的代码是放在<netlib>头文件里。

用户使用我们的库的时候,就要编写他自己的头文件<mynetlib>,包含下面的内容 :

#include <netlib>
namespace net = net_33843894;

他创建了一个在本工程内有效的别名,用来代表 提供给他的库中的命名空间。如果名称net已经被别的库使用了,那么他还可以另选一个名字 代替,例如:net2,sock,或者别的什么。

这样就万事大吉了么?还没有。你还要做一件事:使你的库用起来更简单、更方便。在这 个讲究完美的社会里,人们双击一个安装文件后,你的库在他们的开发环境里就应该是可用 的,接下来就是#include <netlib>,再接下来他们就可以去忙别的了。

然而,现在的情况是,用户为了使用你的库需要创建一个他自己的头文件,虽然这并没有 什么大不了的,但不是每个用户都能忍受这一点。解决的方法就是直接提供一个合理的缺省 值,如果用户觉得不合适也可以取消,所以,在你的头文件里使用预编译选项,如下:

namespace net_33843894 {
  class Socket {
    ...
  };
}
#ifndef NO_NET_33843894_ALIAS
  namespace net = net_33843894;
#endif

这样我们就给命名空间的名字提供了一个缺省值,如果这个名字已经有人用了 ,那么用户可以定义一个NO_NET_33843894_ALIAS宏,别名就会被取消。

不幸的是,即使是使用了短的别名net,当你使用Socket类的方法不对的时候,在我所用 过的编译器中,没有一个能够在错误提示信息里显示的短的别名,而是仍然使用 net_33843894::Socket。读起来有些费劲。

怎么办?看我的。

#ifdef NO_NET_33843894_ALIAS
namespace net_33843894 {
#else
namespace net {
#endif
  class Socket {
    ...
  };
}
#ifndef NO_NET_33843894_ALIAS
  namespace net_33843894 = net;
#endif

如果没有定义宏NO_NET_33843894_ALIAS, 就直接给命名空间起个短一点的名 字,把别名弄长点就可以了。这样,错误信息读起来就会顺眼多了。

时间: 2024-11-02 22:04:33

正确使用namespace(命名空间)的相关文章

亲密接触ASP.Net(6) Namespace(命名空间)的使用

关于Namespace(命名空间)的使用 在前面的程序中我们看到,我常用<% @ Import Namespace="System.Data" %>,这是在引用M$为我们提供的Namespace,这和ASP不同的,我们在ASP.net必须先引用与我们操作有关的Namespace后才能使用相应的功能.其实说白了,一个Namespace; 就是一个组件.这个是关于ASP.net的高级应用,我会在后面的章节讲.(不过要写到那里,时间......) 我下面简单的列举一些常用的Nam

PHP namespace 命名空间详解

在这里中我们介绍了php教程命名空间的用途和namespace关键字,在这篇文章中我们将介绍一下use命令的使用以及php如何解析命名空间的名字的. namespace bakbaba; function bab(){     echo "bi"; } namespace kkk; function k1(){     echo "k1"; } bakbababab();//在kkk的命名空间下使用别的命名空间,注意前面的 use bakbaba as b;//依旧

PHP6 的namespace 命名空间

php有namespace或类似的东西的.对于发布类库框架,或者构建大的程序来说是很重要的.可以避免类名和函数名冲突,又不用像Pear里那样把类名弄得老长.当初php5的测试版曾经出现过,后来正式发布时又取消了,让我空欢喜一场.7月初,php6的snap里又加入了namespace,希望这次不要再让我空欢喜了. 这次的namespace实现和当初的实现有所不同,更接近于C++的语法. 声明namespace时在文件里加上例如 namespace blogbus::test; function f

JavaScript namespace命名空间使用说明

写C或者JAVA习惯的人写JavaScript时可能会发现JavaScript并没有命名空间这一概念,当然如果没有接触过命名空间的程序猿(比如写js,PHP,Python)也可能对命名空间不关注或者不重视.这样的情况普遍存在,见过不少人写JavaScript时直接就全局变量的写,如:  代码如下 复制代码 function a(){   }   function b(){   } 什么是命名空间呢?语言使用的一种代码组织的形式 通过名称空间来分类,区别不同的代码功能 .无论项目大小,如果一开始不

C++ using namespace std; 表示使用那些命名空间呀?是一种怎么样的形式?

问题描述 C++ using namespace std; 表示使用那些命名空间呀?是一种怎么样的形式? 比如说#include是包含一个文件,文件有趣连接一个源文件,当时命名空间是一个什么呢? 是一个库吗?是一个文件吗? 命名空间是定义的什么地方的? 或者说是一个什么东西 解决方案 标准C++引入命名空间,除了可以避免成员的名称发生冲突之外,还可以使代码保持局部性,从而保护代码不被他人非法使用.如果你的目的主要是后者,而且又为替命名空间取一个好听.有意义.且与别人的命名空间不重名的名称而烦恼的

PHP命名空间(namespace)的使用基础及示例_php实例

PHP的命名空间(namespace)是PHP 5.3中加入最重要的一个新特性,这个概念在C#中已经很早就有了,php中的namespace其实和c#的概念是一样的. 一. PHP的命名空间主要解决三种冲突的问题:常量,函数,类 通俗理解:namespace就相当于是用来建一个目录,将namespace下面的代码放在该目录里面,与外面的区分开来. /* |--------------------------------- |namespace示例 |@黑眼诗人 <www.chenwei.ws>

ASP.Net中命名空间Namespace浅析和使用例子_实用技巧

关于Namespace(命名空间)的使用,我常用 复制代码 代码如下: < % @ Import Namespace="System.Data" %> ,这是在引用为我们提供的Namespace,这和ASP不同的,我们在ASP.net必须先引用与我们操作有关的Namespace后才能使用相应的功能.其实说白了,一个Namespace; 就是一个组件. 这个是关于ASP.net的高级应用. 我下面简单的列举一些常用的Namespace 复制代码 代码如下: < % @

PHP命名空间namespace用法实例分析_php技巧

本文实例讲述了PHP命名空间namespace用法.分享给大家供大家参考,具体如下: namespace(命名空间)相当于函数.类,划分了一个区域,这样子就使得在同个页面中可以require相同的类,使用相同名字的函数 : 在项目中比较少用 name.php: <?php //命名要使用复合名称 namespace me\mine; class me{ public function __construct(){ echo 'name'.'<br>'; } public function

浅谈几种常见语言的命名空间(Namespace)_C 语言

命名空间提供了一种从逻辑上组织类的方式,防止命名冲突. 几种常见语言 C++ 命名空间是可以嵌套的 嵌套的命名空间是指定义在其他命名空间中的命名空间.嵌套的命名空间是一个嵌套的作用域,内层命名空间声明的名字将隐藏外层命名空间声明的同名成员: int x = 20; namespace outer { int x = 10; namespace inner { int z = x; } } int main() { std::cout << outer::inner::z; // 输出10 re