为什么非静态变量不能驻留在头文件中?
举个例子:
// myheader.h
static int myStaticVar = 0;
// If we remove 'static' the compiler will throw linker error.
void DoStuff();
// and myheader.cpp, and main.cpp; etc
我是这样解释的:
静态变量没有外部链接,当我们编译时 如果没有“static”,我们将“包含”静态变量(即 此处为全局)在每个文件中,这会创建重复项并且链接器将 由于不允许多重声明,因此会抛出错误。
有没有更好的方法来解释这一点?谢谢。
PS:我们是否应该在头文件中包含静态变量(不谈论成员)?
Take for example:
// myheader.h
static int myStaticVar = 0;
// If we remove 'static' the compiler will throw linker error.
void DoStuff();
// and myheader.cpp, and main.cpp; etc
This is how I would explain it:
Static variables do not have external linkage, and when we compile
without 'static' we are "including" the static variable (which is
global here) in every file, which create duplicates and linker will
throw an error since multiple declaration is not allowed.
Is there any better way to explain this? Thanks.
PS: Are we suppose to have static variables (not talking about members) in header file?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
因为它违反了单一定义规则(ODR)。
当您包含包含非静态变量的头文件时,该变量的声明将粘贴到包含该变量的每个源文件中。因此,您最终会在同一个 翻译单元,这违反了 ODR,因此链接器会给您链接错误。
当您在头文件中声明静态变量时,会在每个 翻译单元,其中包含头文件。
在头文件中声明静态变量不会给您带来多个定义错误,但它无法实现拥有一个全局变量的目的,该全局变量的值在访问它的所有文件之间共享。
您可能认为由于您使用的是全局静态变量,因此它的值将在不同的文件中保留,但如上所述,每个翻译单元都有自己的变量副本,并且它没有实现您认为要实现的目标。
不,从来没有!
您需要使用
extern
关键字。在头文件中添加变量的外部声明。定义变量的一个源文件以及引用该变量的所有源文件都应包含标头。 只有一个源文件应该定义变量。另外,只有一个头文件应该声明该变量。
文件名.h
file1.cpp
file2.cpp
Because it breaks the One Definition Rule(ODR).
When you include the header file containing a non-static variable, the declaration of the variable gets pasted in each source file where it is included. Thus, you end up having more than one definition of a variable, in the same Translation Unit, this violates the ODR, and hence, the linker will give you linking errors.
When you declare a static variable in a header file, a copy of the variable gets created in each Translation Unit where the header file is included.
Declaring a static variable in the header file will not give you multiple definition errors, but it does not achieve your purpose of having a global variable whose value is shared across all files which access it.
You may think that since you are using a global static variable, its value will be retained across different files, but as mentioned above, each Translation Unit has its own copy of the variable, and it does not achieve what you think you are achieving.
No, Never!
You need to use the
extern
keyword.Add the extern declaration of the variable in a header file. The header should be included by the one source file that defines the variable, and by all the source files that reference the variable. Only one source file should define the variable. Also, only one header file should declare the variable.
filename.h
file1.cpp
file2.cpp
首先,阅读类似问题的此答案。
为了根据您的问题补充答案,这里是:
当您
#include
文件(任何文件,.h
文件是常见约定)时,它几乎基本上只是将其复制粘贴到您的代码中。如果头文件中有非静态变量,并将其包含在两个源文件中,该变量将被复制粘贴到两个源文件中,并且您会收到链接错误,正如我在答案中解释的那样我告诉过你读上面的内容。如果您想在多个源文件之间共享全局变量,您应该这样做:
在 仅一个 源文件中:
在头文件中:
这样,所有源文件都可以看到将成为一堆源文件中某处的
global_var
。只有一个源文件实际上包含该变量,并且当发生链接时,所有源文件都将引用global_var
的一个实例First, read this answer to a similar question.
To complement the answer based on your question, here goes:
When you
#include
a file (any file,.h
files is a common convention), it almost basically just copy-pastes it in your code. If you have non-static variable in the header file and you include it in two source files, the variable gets copy-pasted in both source files and well you get a link error as I explained in the answer I told you to read above.If you want to share a global variable across many source files, you should do this:
In only one of your source files:
In the header file:
So, this way, all the source files see there is going to be a
global_var
somewhere in the bunch of source files. Only one of the source files actually contains that variable and when linking happens, all the source files would be referring to that one instance ofglobal_var
头文件 (.h) 告诉您(声明)定义文件 (.cpp) 将做什么。
打个比喻——头文件就像告诉很多朋友你要做某件事,但实际上你只会做一次。
The header file (.h) tells you (declares) what the definition file (.cpp) will do.
For a metaphor - a header file is like to telling a lot of friends that you are going to do something, but in reality you are going to do it once.