它应该在命名空间中吗?

时间:2010-04-11 13:29:56

标签: c++ namespaces

我是否必须将.cpp中的代码放在来自相应.h的命名空间中,或者只是使用声明来编写?

//file .h
namespace a
{
/*interface*/
class my
{
};
}

//file .cpp

using a::my; // Can I just write in this file this declaration and
             // after that start to write implementation, or
             // should I write:

namespace a //everything in a namespace now
{
//Implementation goes here
}

感谢。

3 个答案:

答案 0 :(得分:4)

我认为更合适的是围绕namespace a { ... }块中命名空间中的所有代码,因为这在语义上是你正在做的:你在a命名空间中定义元素。但如果你只是定义成员,那么这两件事都可行。

当编译器找到void my::foo()时,它将尝试确定my是什么,它会找到using a::my,从中解析my并了解您是定义a::my::foo方法。

另一方面,如果您使用免费功能,这种方法将失败:

// header
namespace a {
   class my { // ... 
   };
   std::ostream & operator<<( std::ostream& o, my const & m );
}
// cpp
using a::my;
using std;
ostream & operator<<( ostream & o, my const & m ) {
   //....
}

编译器很乐意将上面的代码翻译成一个程序,但它实际上做的是在头文件中声明std::ostream& a::operator<<( std::ostream&, a::my const & ) - 没有实现 - ,并在cpp文件中定义std::ostream& ::operator<<( std::ostream &, a::my const & ) ,这是一个不同的功能。使用Koening查找,只要编译器看到cout << obj类型为obj的{​​{1}},编译器就会查找a::mycout({{}的封闭名称空间。 1}}和my)并且会发现std已声明,但从未在a中定义。它将编译但不链接您的代码。

答案 1 :(得分:1)

如果我正确理解了这个问题,你可以只使用一个:: my然后实现这些方法,比如

using a::my;

void my::doSomething() {}

答案 2 :(得分:0)

可以做到这一点。但是,应该你呢?

这是一种不常见的做法,它可能会导致.cc文件中使用的命名空间“a”中每种类型的using a::Type;扩散。这是否是一件好事,由你来决定,但我会反对它:)