命名空间范围内的静态关键字无用?
Posted
技术标签:
【中文标题】命名空间范围内的静态关键字无用?【英文标题】:static keyword useless in namespace scope? 【发布时间】:2011-08-27 10:32:23 【问题描述】:namespace N
static int x = 5;
在命名空间范围内声明具有静态变量的重要性/用例是什么?
【问题讨论】:
我认为不鼓励使用static
;改用未命名的命名空间。
@ereOn:不是真的。 C++03 已弃用它,但 C++11 已弃用它。为什么?因为它在某些方面很有用。
【参考方案1】:
我同意 Nawaz 的回答:static 关键字在命名空间中并非完全没用:它定义了变量与翻译单元的内部链接。
例如: header.h
namespace test
static int i = 5;//definition is here.And there will be no multiple definition!
void set_i();
void print_i();
header.cpp
#include "header.h"
#include "iostream"
void test::set_i()
i = 10;
return;
void test:print_i()
using namespace std;
cout << "print_i is " << i << endl;
return;
main.cpp
#include "header.h"
#include "iostream"
using std::cout;
int main()
test::i = 20;
test::set_i();
cout << "i is " << test::i << endl;
test::print_i();
return 0;
使用g++ -std=c++11 header.cpp main.cpp
编译,不会得到multiple definition error
。如果去掉static
关键字再编译,肯定是multiple definition error
。请运行程序并观察结果,您可能会感到惊讶。
static
关键字使每个包含接口头的 cpp 实现文件(翻译单元)都具有静态变量的内部链接副本。因此,即使您在命名空间中定义该变量,如果它是 static
关键字,也不会出现多重定义错误。(const
与前面没有 extern
相同,它定义了内部链接的变量,这就是宏的方式可以在 C++ 中丢弃)因此,在命名空间中定义的变量是隐式静态的说法是错误的,静态在命名空间中并非完全没用。因为每个翻译单元都有该变量的一份副本,所以会占用空间。
但是,未命名的命名空间可以使其他翻译单元无法访问其中的类声明,而 static
关键字不能“属性”一个类,因此这是未命名命名空间的一个优点。此外,您可以在嵌套命名空间中使用未命名命名空间来限制变量访问。未命名的命名空间旨在保护局部性,而不是提供接口。
【讨论】:
【参考方案2】:C++ 标准§7.3.1.1/2:
static关键字的使用是 在 a 中声明对象时不推荐使用 命名空间范围(见附件 D);这 unnamed-namespace 提供了一个优越的 替代。
除非未命名的命名空间在未来的标准it will be undeprecated 中提供更好的替代方案以实现 C 兼容性。
【讨论】:
这不是在 2011 年被弃用了吗? 我相信 C++0x 标准在这种情况下不会弃用static
,不是吗?
在最后的草稿中,这一段是存在的,但被删除了,所以我不确定。
有趣。我想你不能对尚未最终确定的标准认为任何事情都是理所当然的。
@Neil 范围不是问题; static
不影响范围。 “类”(即:类的名称及其所有成员的名称)具有外部链接,除非它们是本地的(在函数中定义)。因此,如果我在我的翻译单元中定义 class C public: C(); ;
,而您也这样做,C::C
在两者中都指代相同的实体。如果我们都定义它,我们可能会在链接时得到重复的定义。 (正式地,这是未定义的行为。)而且你无法让static
应用于一个类;这就是引入未命名命名空间的真正原因。【参考方案3】:
附录 D(兼容性功能)[C++03]
D2:在命名空间范围内声明对象时,不推荐使用 static 关键字。
如this 帖子中所述,使用未命名的命名空间。
static 关键字在 C 和 C++ 中的命名空间范围内赋予变量/对象的内部链接,正如其他人在他们的帖子中提到的那样。
附注:
根据最新草案 (n3290),该功能已不推荐。在 n3225 中,§7.3.1.1/2
存在但被删除。
【讨论】:
+1,此外,虽然没有特别的原因不能使用未命名的命名空间完成此操作,但一些编译器为static
链接函数提供了更多诊断(例如在翻译中未使用符号时的警告单位)【参考方案4】:
其他人已经说过,还有一点微妙之处:静态引入了内部链接,而匿名命名空间则没有。
【讨论】:
【参考方案5】:static
命名空间范围内的变量(全局或其他)具有内部链接。这意味着,它不能从其他翻译单元访问。它是声明它的翻译单元的内部。
【讨论】:
这是一个更好的答案,因为它解释了static
在命名空间范围内的作用。不是什么都不做,也不是没用。【参考方案6】:
与在全局命名空间中声明一个静态变量相同,但仅对特定命名空间是本地的。
【讨论】:
以上是关于命名空间范围内的静态关键字无用?的主要内容,如果未能解决你的问题,请参考以下文章