C++ 如何使用命名空间中的变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11478152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to work with variable in namespace
提问by dsollen
I think I hvae a fundamental misunderstanding of namespace and/or static variable. But I have tried this test code (typed by hand, forgive typos)
我认为我对命名空间和/或静态变量存在根本性的误解。但是我试过这个测试代码(手工输入,请原谅错别字)
test.h:
测试.h:
namespace test{
static int testNum=5;
void setNum(int value);
}
main.cpp:
主.cpp:
#include <test.h>
int test::setNum(int value){
testNum=value;
}
int main(){
test::setNum(9);
cout<<test::testNum;
}
when I run this I get the value 5, not 9 as I would have expected. It seems almost as if I have two instances of the testNum variable, but that seems to be the exact opposite of what static should be doing. I'm guessing I've made a mistake in assuming that these features were identical to their java equvilants somehow...
当我运行它时,我得到的值为 5,而不是我预期的 9。看起来好像我有两个 testNum 变量的实例,但这似乎与 static 应该做的完全相反。我猜我犯了一个错误,假设这些功能在某种程度上与它们的 Java 等效项相同......
I also get an error stating that testNum is declared multuple times if I remove the static from my declaration of testNum, could someone explain why that is the case as well?
如果我从 testNum 的声明中删除静态,我也会收到一个错误,指出 testNum 被多次声明,有人可以解释为什么会这样吗?
Thank you
谢谢
回答by Jonathan Wakely
First, your misunderstanding has nothingto do with namespaces, it's only about static
. For the rest of this answer I'm going to refer to simply testNum
because the fact it's in a namespace is irrelevant.
首先,您的误解与名称空间无关,仅与static
. 对于这个答案的其余部分,我将仅参考它,testNum
因为它位于命名空间中的事实无关紧要。
I'm also assuming you have another file, probably called test.cpp
, which also includes test.h
and defines the setNum
function.
我还假设您有另一个文件,可能名为test.cpp
,其中还包含test.h
并定义了该setNum
函数。
When a variable or function at namespace-scope (i.e. not a class member or local to a function) is declared static
it means the entity's name is internal to that file. Formally it has "internal linkage", meaning it can't be referred to by name or linked to from other files (it can be indirectly referred to through a pointer or by passing it as an argument to another function.) That means if several files define static int testNum
then each file has its own internal variable with that name, distinct from the testNum
in every other file (in fact one file could have static int testnum
and another could have static double testnum
and another static char* testNum
, they'd all be distinct and internal to each file.) If you put a definition like that in header then every file that includes the header has its own testNum
.
当命名空间范围内的变量或函数(即不是类成员或函数的局部变量)被声明时,static
这意味着实体的名称是该文件的内部名称。正式它具有“内部链接”,这意味着它不能通过名称引用或从其他文件链接(它可以通过指针间接引用或将其作为参数传递给另一个函数。)这意味着如果有几个文件定义static int testNum
,然后每一个文件都有与该名称其自身的内部变量,从不同testNum
的所有其他文件(实际上是一个文件可以有static int testnum
和另一个可能有static double testnum
和另一个static char* testNum
,他们全是不同的和内部的每个文件。)如果您将这样的定义放在 header 中,然后每个包含 header 的文件都有自己的testNum
.
So with static
on your variable in a header you have a differentvariable called testNum
in every file that includes test.h
. That means if you set testNum
in one file and call a function in a different file which uses testNum
it refers to a differentvariable, which just happens to have the same name.
因此,与static
上一个头的变量,你有一个不同的叫做变量testNum
在每一个包含文件test.h
。这意味着如果您testNum
在一个文件中设置并调用另一个文件中的函数,该函数使用testNum
它引用不同的变量,而该变量恰好具有相同的名称。
Because of this, declaring non-const static
variables in headers is almost always wrong.
因此,static
在标头中声明非常量变量几乎总是错误的。
Without static
you would have a definition of the testNum
variable in every file that includes test.h
, which is not allowed: every entity must be defined once and once only in your program. The way to solve that is to declarethe variable in the header, but not defineit, which you do by telling the compiler the variable is extern
:
如果没有,static
您将testNum
在每个包含 的文件中定义变量test.h
,这是不允许的:每个实体必须在您的程序中一次又一次地定义。解决这个问题的方法是在头文件中声明变量,但不定义它,你通过告诉编译器变量是extern
:
extern int testNum; // N.B. no "= 1" here
That tells the compiler there is a variable with "external linkage" called testNum
, so when code refers to testNum
it will always mean the same variable (not some name with internal linakge that is a different entity in every file.) After declaring an extern
variable it is your responsibility to ensure there is exactly one definition provided somewhere in the program, so in exactly onefile (i.e. not in a header that gets included in multiple files) you define it:
这告诉编译器有一个名为“外部链接”的变量testNum
,因此当代码引用testNum
它时,它总是意味着相同的变量(不是某个具有内部链接的名称,它是每个文件中的不同实体。)声明extern
变量后,它是您有责任确保在程序中的某处恰好提供了一个定义,因此在一个文件中(即不在包含在多个文件中的头文件中)您定义它:
int testNum = 1;
回答by James Kanze
static
at namespace scope is a misnomer, and shouldn't be used. It
means simply that the entity declared static has internal name binding;
in other words, that the same name in other translation units will refer
to a different entity, and in the case of variable definitions, that
there will be a separate instance of the variable in each translation
unit. It has no effect on lifetime. (Allvariables declared or
defined at namespace scope have static lifetime.)
static
在命名空间范围内用词不当,不应使用。这意味着声明为 static 的实体具有内部名称绑定;换句话说,其他翻译单元中的相同名称将指代不同的实体,并且在变量定义的情况下,每个翻译单元中将有一个单独的变量实例。它对寿命没有影响。(在命名空间范围内声明或定义的所有变量都具有静态生命周期。)
static
at namespace scope is also deprecated. Don't use it.
static
在命名空间范围内也已弃用。不要使用它。
With regards to declaring a variable in a header: prefix it with
extern
, and not static
. If a variable is declared extern
, and
there is no initialization, the declaration is not a definition. Of
course, in this case, you must provide a definition somewhere (in a
single source file). Something along the lines of:
关于在标头中声明变量:前缀为
extern
, 而不是static
。如果声明了变量extern
,并且没有初始化,则声明不是定义。当然,在这种情况下,您必须在某处(在单个源文件中)提供定义。类似的东西:
extern int testNum = 5;
int testNum = 5;
int testNum; // implicitly initialized with 0.
EDIT:
编辑:
To clarify somewhat: there is some confusion here between lifetime and name binding:
澄清一下:生命周期和名称绑定之间存在一些混淆:
- an object has a lifetime (auto, static or dynamic—or temporary, or exception), and
- a name is bound to an entity; if the name is declared to be a variable, the entity is an object.
- 对象具有生命周期(自动、静态或动态——或临时或异常),并且
- 名称绑定到一个实体;如果名称被声明为变量,则实体是一个对象。
Do notconfuse the keyword static
with static lifetime. (Functions
can be static
, but functions have no defined lifetime in C++; they're
just there.)
千万不能混淆的关键词static
静态寿命。(函数可以是static
,但函数在 C++ 中没有定义的生命周期;它们就在那里。)
The rules regarding these are not very orthognal. Basically, with regards to lifetime:
关于这些的规则不是很正交。基本上,关于生命周期:
- all variables declared at namespace scope have static lifetime, always,
- variables declared at local scope have auto lifetime unlessthey are declared
static
, and - variables declared at class scope have the lifetime of the class object which contains them, unless they are declared
static
. regards to lifetime.
- 在命名空间范围内声明的所有变量都具有静态生命周期,始终,
- 在局部范围内声明的变量具有自动生存期,除非它们被声明
static
,并且 - 在类范围内声明的变量具有包含它们的类对象的生命周期,除非它们被声明
static
。关乎一生。
Objects with static lifetime come into being sometime before main
, and
live until after you return from main
.
具有静态生命周期的对象在某个时间之前出现main
,并一直存在到您从main
.
With regards to name binding:
关于名称绑定:
- variables declared at namespace scope have external name binding,
unless they are declared
static
, in which case they have internal name binding (but this use ofstatic
is deprecated), or if they areconst
, and are not declaredextern
, - variables declared at class scope have external name binding, even if they are declared
static
, and - variables declared at block scope have no binding.
- 在命名空间范围内声明的变量具有外部名称绑定,除非它们被声明
static
,在这种情况下它们具有内部名称绑定(但static
不推荐使用 ),或者如果它们是const
,并且未声明extern
, - 在类范围内声明的变量具有外部名称绑定,即使它们被声明
static
,并且 - 在块范围内声明的变量没有绑定。
Finally, there is the question of whether a declaration is a definition
or not. If it is a definition, memory is allocated and the object is
(or may be) initialized. If it is not a definition, it simply tells the
compiler that there is a definition somewhere else for the entity
(object) declared in the declaration. In general, a variable
declaration is a definition unlessit is declared extern
and does
nothave an initializer.
最后,还有一个声明是否是定义的问题。如果是定义,则分配内存并初始化(或可能)对象。如果它不是定义,它只是告诉编译器在声明中声明的实体(对象)在其他地方有一个定义。一般情况下,一个变量声明是一个定义,除非它被声明extern
并没有
不有初始值。
回答by Adam
You might want to make sure your code actually has problems before you post it asking what's wrong ;)
在发布之前,您可能想确保您的代码确实有问题,询问出了什么问题;)
I copy/pasted and fixed your typos, and manually did the include:
我复制/粘贴并修复了您的错别字,并手动完成了包括:
#include <iostream>
using namespace std;
namespace test{
static int testNum=5;
void setNum(int value);
}
void test::setNum(int value){
testNum=value;
}
int main(){
test::setNum(9);
cout<<test::testNum;
}
result:
结果:
$ ./a.out
9
What you haven't said is what else is in your program. If you have more than just main.cpp, and include your test.h, then each .cpp file will have its own copy of testNum. If you want them to share then you need all but one to mark it as extern
.
你没有说的是你的程序中还有什么。如果您不仅有 main.cpp,而且包含您的 test.h,那么每个 .cpp 文件都将拥有自己的 testNum 副本。如果您希望他们共享,那么您需要将其标记为extern
.