未命名名称空间优于静态名称空间?

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

47016 次浏览

你基本上是在引用 C + + 03标准中的7.3.1.1/2节,

Static 关键字的用法是 中声明对象时弃用 命名空间范围; 未命名的命名空间提供了一个上级 另一种选择。

注意,这个段落已经在 C + + 11中删除了。 static函数不再被弃用!

尽管如此,未命名的 namespace优于 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 */ };
}

希望能够解释为什么未命名的 namespace优于 static

另外,请注意,在命名空间范围中声明对象时(按照 Standard)不推荐使用 static 关键字。

这里有一个有趣的问题:

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

随着时间的推移,模块实现的源文件会变得越来越大,您希望将其分成几个单独的源文件,这样可以更好地组织代码,更快地查找定义,并且可以独立编译。

但是现在您面临一个问题: 这些函数不再是模块的 static,因为 static实际上并不引用 模组,而是引用 源文件(翻译单元)。您必须使它们非 static,以允许从该模块的其他部分(目标文件)访问它们。但是这也意味着它们不再隐藏/私有到模块: 有外部链接,它们可以从其他模块访问,这是 没有的初衷。

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

如果能够指定某个 namespaceprivate就太好了,也就是说,无论 namespace中定义了什么,它都应该由它所属的模块在内部使用。但是当然 C + + 没有“模块”这样的概念,只有“翻译单元”,它们紧密地绑定在源文件上。