147

未命名的命名空间如何优于static关键字?

4

2 回答 2

154

您基本上是指 C++03 标准中的第 7.3.1.1/2 节,

在命名空间范围内声明对象时,不推荐使用 static 关键字;unnamed-namespace 提供了一个更好的选择。

请注意,此段落已在 C++11 中删除。static功能按标准不再被弃用!

尽管如此, unnamednamespace优于 static 关键字,主要是因为该关键字static仅适用于变量声明和函数,而不适用于用户定义的类型

以下代码在 C++ 中有效:

//legal code
static int sample_function() { /* function body */ }
static int sample_variable;

但此代码无效:

//illegal code
static class sample_class { /* class body */ };
static struct sample_struct { /* struct body */ };

所以解决方案是,未命名(又名匿名)namespace,即:

//legal code
namespace 
{  
     class sample_class { /* class body */ };
     struct sample_struct { /* struct body */ };
}

希望它能解释为什么 unnamednamespace优于static.

另外,请注意,在命名空间范围内声明对象时(根据标准),不推荐使用 static 关键字。
于 2010-12-12T16:10:51.273 回答
10

有一个与此相关的有趣问题:

假设您使用static关键字或未命名namespace来使模块内部的某些函数(翻译单元),因为此函数旨在由模块内部使用,而不能在模块外部访问。(除了函数之外,Unnamednamespace还具有使数据和类型定义在内部的优点)。

随着时间的推移,你的模块实现的源文件变得越来越大,你想把它分成几个单独的源文件,这样可以更好地组织代码,更快地找到定义,并且可以独立编译。

但是现在你面临一个问题:那些函数不能再static指向模块,因为static实际上并不是指向模块,而是指向源文件(翻译单元)。您被迫将它们static设为非允许从该模块的其他部分(目标文件)访问它们。但这也意味着它们不再对模块隐藏/私有:具有外部链接,可以从其他模块访问它们,这不是您的初衷。

Unnamednamespace也不能解决这个问题,因为它也是为特定的源文件(翻译单元)定义的,不能从外部访问。

如果可以指定 some namespaceis private,那就太好了,也就是说,其中定义的任何内容都旨在由其所属的模块在内部使用。但是当然 C++ 没有“模块”这样的概念,只有“翻译单元”,它们与源文件紧密绑定。

于 2014-03-27T09:01:36.270 回答