标题中两者之间是否存在语义差异?
例如,我可以写,
class Hi{
public:
static void Print(){
printf("hi\n");
}
};
但是,
namespace Hi{
inline void Print(){
printf("hi\n");
}
}
我当然假设这两个定义都在标题中。这只是风格问题吗?
答案 0 :(得分:1)
主要区别在于可以扩展名称空间,而可以继承类。这种差异对于" enum包装"在C ++ 03中。有些人强烈赞成在类中包装枚举,而其他人则强烈赞成将它们包装在命名空间中,而大多数人都不关心并且没有包装。
命名空间支持依赖于参数的查找,而类不是(除了在类定义中定义的友元函数的调用,然后它真正命名空间ADL)。
类不支持访问控制(公共,受保护,私有),而名称空间则不支持。对于名称空间,与私有访问相对应的技术是名为detail
或impl
的嵌套名称空间或类似名称空间。但这只是惯例,而不是编译器可以检查和执行的内容。
我想,由于以上是我首先想到的,它可能是最相关的。
值得注意的是:使用类作为一种虚假命名空间机制的库确实存在(特别是我遇到了那种类型的XML解析器库),但它们非常罕见,我怀疑除了可能的上述枚举包装外,任何新的库都会这样做,但是C ++ 11的范围枚举使得它变得不那么重要了。
答案 1 :(得分:1)
虽然第一个示例中的类充当临时命名空间,但差异不仅限于样式。
例如,静态成员函数可以访问类的私有成员,例如同一个类的其他静态函数,类中定义的私有类型,以及类中定义的私有静态变量。
您可以使用在翻译单元范围内定义的名称空间和静态非成员函数/变量来模拟许多此行为。但是,当类的非静态成员需要与静态成员函数共享对私有成员的访问时,仿真将不完整。在这种情况下,您需要提供额外的功能来将私有成员公开给非成员,而成员函数则可以免费获得。
以下是基于您的代码的示例:
class Hi{
private:
// This static member variable is defined in a cpp file
static int count;
public:
Hi() { // Let's pretend concurrency does not exist
count++;
}
static void Print(){
printf("You said Hi %d times\n", count);
}
};
如果您想使用命名空间模拟上述行为,则需要声明您的Hi::Print
是某个类的朋友,或者提供公共函数以获取count
的当前值。