namespace N
{
static int x = 5;
}
在命名空间作用域中声明静态变量有什么重要性/用途?
namespace N
{
static int x = 5;
}
在命名空间作用域中声明静态变量有什么重要性/用途?
静态
变量在命名空间范围(全局或其他)具有内部链接。这意味着它无法从其他翻译单元访问。它是在声明它的翻译单元内部的。
static
在命名空间作用域中所起的作用。它不是没有作用,也不是无用的。 - John Dibling附录 D(兼容性特征)[C++03]
D2:在命名空间作用域中声明对象时,使用 static 关键字已被弃用。
请改用未命名的命名空间,如此贴所述。
正如其他人在他们的帖子中提到的那样,static 关键字在 C 和 C++ 中都会为变量/对象提供内部链接。
P.S:
根据最新草案(n3290),该功能已被取消弃用。 在 n3225 中,§7.3.1.1/2
虽然存在,但已被删除线划掉。
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
关键字,就不会出现多重定义错误。(对于没有带有 extern
的 const
来定义具有内部链接的变量也是同样的道理,这就是 C++ 中如何丢弃宏定义的。) 因此,“在命名空间中定义的变量隐式为 static”这种说法是错误的,而 static 在命名空间中其实并非完全没用处。由于每个实现单元都有变量的一个副本,因此会消耗空间。static
关键字则不能“属性”一个类,因此这是未命名的命名空间的一个优势。此外,你可以在嵌套命名空间中使用未命名的命名空间来限制变量的访问。未命名的命名空间是为了保护局部性而设计的,而不是提供接口。C++标准§7.3.1.1/2:
在命名空间作用域中声明对象时,使用static关键字已被弃用(请参见附录D);未命名的命名空间提供了更好的替代方案。
除非未命名的命名空间在未来的标准中提供了更好的替代方案(它将被取消弃用)以实现C兼容性。
static
的弃用,不是吗? - Fred Larsonstatic
不影响范围。 "类"(即:类的名称和所有成员的名称)具有外部链接,除非它们是局部的(在函数中定义)。因此,如果我在我的翻译单元中定义了 class C { public: C(); };
,而你也这样做了,C::C
在两者中都指向同一实体。如果我们都定义它,链接时可能会得到重复定义。(严格来说,这是未定义行为。)而且你无法使 static
应用于一个类;这就是为什么引入了匿名命名空间的原因。 - James Kanze与在全局命名空间中声明静态变量相同,但仅限于特定命名空间。
其他人已经说过了,还有一个微妙之处:static引入了内部链接,而匿名命名空间则没有。
static
,而应该使用未命名的命名空间。 - ereOn