在标头和源(cpp)中创建C ++命名空间


87

将标头和cpp文件内容都包装在名称空间中还是只包装标头内容然后在cpp文件中使用名称空间之间有什么区别吗?

区别是指可能导致问题或我需要注意的任何排序性能损失或稍微不同的语义。

例:

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
namespace X
{
  void Foo::TheFunc()
  {
    return;
  }
}

VS

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
using namespace X;
{
  void Foo::TheFunc()
  {
    return;
  }
} 

如果没有区别,首选形式是什么,为什么?

Answers:


37

命名空间只是一种处理函数签名的方法,这样它们就不会发生冲突。一些人喜欢第一种方式,而另一些人喜欢第二种方式。这两个版本对编译时性能均没有任何影响。请注意,名称空间只是一个编译时实体。

使用名称空间所引起的唯一问题是当我们具有相同的嵌套名称空间名称(即)时X::X::Foo。无论是否使用关键字,这样做都会造成更多的混乱。


54

“命名空间X”与“使用命名空间X”的区别在于,第一个新声明将在名称空间下,而在第二个声明中则不会。

在您的示例中,没有新的声明-因此没有区别,因此没有首选的方式。


这取决于项目和样式。通常,在模块中有一个用于加载文件的主要名称空间,第二种样式很有意义。
尼古拉斯·威尔逊,

8

没有性能上的损失,因为结果可能是相同的,但是如果将s放在不同的命名空间中,则将您的Foo名称空间隐式地引入歧义Foo。的确,您可以获取代码fubar。我建议避免using为此目的使用。

然后你流浪{using namespace;-)


我不会称其为流浪,因为它与结尾}处的结尾相符。但是,我称这对括号为多余;)
blubberdiblub

@blubberdiblub,问题已被编辑,如果您检查了原始版本,您称其为流浪;-)
Michael Krelin-hacker

1

如果第二个也可以编译,则应该没有差异。命名空间是在编译时处理的,不应影响运行时操作。

但是对于设计问题,第二个是可怕的。即使编译(不确定),也没有任何意义。


1
我不认为它可以编译,但不是因为有区别,而是因为有一个流浪{;-)
Michael Krelin-hacker

所不同的是美孚:: TheFunc()在全局命名空间中声明,而它在命名空间X.定义
BERT-一月

1

在VS情况下,Foo :: TheFunc()不在正确的名称空间中。使用“ void X :: Foo :: TheFunc(){}”可在正确的名称空间(X)中实现该功能。


这个问题有点老了,但是你知道这会带来什么后果吗?也就是说,您的VS案例在名称空间中声明函数,但在名称空间之外定义函数时会遇到任何问题吗?
亚当·古德温

1

如果确实只包装.h内容,则必须在cpp文件中使用命名空间...编写,否则每次使用有效的命名空间。通常,您同时包装.cpp和.h文件,否则就有使用来自另一个命名空间的对象的风险,这可能会产生很多问题。


0

我认为这里正确的做法是使用名称空间进行作用域。

namespace catagory
{
    enum status
    {
      none,
      active,
      paused
    }
};

void func()
{
    catagory::status status;
    status = category::active;
}

0

如果您尝试使用一个变量到另一个变量,则建议将其外部化,然后在源文件中对其进行初始化,如下所示:

// [.hh]
namespace example
{
   extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
   int a, b, c;
}
// Then in the function below, you can init them as what you want: 
void reference
{
    example::a = 0;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.