我有Java背景,使用的是包,而不是名称空间。我习惯于将一起工作以形成完整对象的类放入包中,然后从该包中重用它们。但是现在我在用c++工作。

在c++中如何使用名称空间?您是为整个应用程序创建单个名称空间,还是为主要组件创建名称空间?如果是,如何从其他名称空间中的类创建对象?


当前回答

我使用c++命名空间的方式与我在c#、Perl等中使用的方式相同。它只是标准库内容、第三方内容和我自己的代码之间的符号语义分离。我会将自己的应用程序放在一个名称空间中,然后将可重用的库组件放在另一个名称空间中进行分离。

其他回答

我在其他答案中没有看到任何提及,所以这里是我的2美分:

在“使用名称空间”主题上,一个有用的语句是名称空间别名,允许您“重命名”名称空间,通常是给它一个更短的名称。例如,不要:

Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally::TheClassName foo;
Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally::AnotherClassName bar;

你可以这样写:

namespace Shorter = Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally;
Shorter::TheClassName foo;
Shorter::AnotherClassName bar;

命名空间本质上是包。它们可以这样使用:

namespace MyNamespace
{
  class MyClass
  {
  };
}

然后在代码中:

MyNamespace::MyClass* pClass = new MyNamespace::MyClass();

或者,如果你想总是使用一个特定的名称空间,你可以这样做:

using namespace MyNamespace;

MyClass* pClass = new MyClass();

编辑:按照bernhardrusch所说,我倾向于不使用“使用名称空间x”语法,我通常在实例化对象时显式指定名称空间(即我展示的第一个示例)。

正如下面所要求的,您可以使用任意数量的名称空间。

java和c++的另一个区别是,在c++中,名称空间层次结构不需要调整文件系统布局。因此,我倾向于将整个可重用库放在一个单独的命名空间中,并将库中的子系统放在子目录中:

#include "lib/module1.h"
#include "lib/module2.h"

lib::class1 *v = new lib::class1();

如果存在名称冲突的可能性,我只会将子系统放在嵌套的名称空间中。

我所见过的大型c++项目很少使用一个以上的命名空间(例如boost库)。

实际上boost使用了大量的名称空间,通常boost的每个部分都有自己的内部工作空间,然后可能只将公共接口放在顶级名称空间boost中。

我个人认为,代码库越大,名称空间就越重要,即使在单个应用程序(或库)中也是如此。在工作中,我们将应用程序的每个模块放在自己的命名空间中。

我经常使用的命名空间的另一种用法(不是双关语)是匿名命名空间:

namespace {
  const int CONSTANT = 42;
}

这基本等同于:

static const int CONSTANT = 42;

然而,使用匿名命名空间(而不是静态命名空间)是在c++中仅在当前编译单元中可见的代码和数据的推荐方式。

一般来说,如果我认为一段代码可能与其他库有函数或类型名称冲突,我会为它创建一个名称空间。它也有助于品牌代码,ala boost::。