C++ 对静态变量的更改超出范围?(C+;+;)
我有一个包含静态变量的头文件,例如窗口宽度和高度 我通过一个XML文件读取这些变量的新值,但一旦所更改的函数超出范围,这些更改似乎就不会被注册 举例说明:C++ 对静态变量的更改超出范围?(C+;+;),c++,C++,我有一个包含静态变量的头文件,例如窗口宽度和高度 我通过一个XML文件读取这些变量的新值,但一旦所更改的函数超出范围,这些更改似乎就不会被注册 举例说明: // These are in a separate header file static int width = 0; static int height = 0; aClass::Init() { width = readFromXMLFile(); // returning 800 height
// These are in a separate header file
static int width = 0;
static int height = 0;
aClass::Init()
{
width = readFromXMLFile(); // returning 800
height = readFromXMLFile(); // returning 600
// Here width and height are 800/600
}
aClass::Run()
{
...
}
Main
{
Init()
// Here, width and height are 0/0 again
Run()
}
如果不在某个地方将静态声明为extern,那么最终得到的实际上是每个编译单元的多个静态副本(同名) 正确的例子: 测试h
extern int mystatic;
test.cpp
int mystatic = 0;
void myFunction() // or member funciton, who cares
{
mystatic = 42;
}
main.cpp
#include "test.h"
int main()
{
std::cout << mystatic << std::endl; // prints 0
//
myFunction(); // or use classes and trigger the same
//
std::cout << mystatic << std::endl; // prints 42
return 0;
}
#包括“test.h”
int main()
{
std::cout您应该在头文件中声明静态变量,extern
ed并在cpp文件中定义它们
.h文件:
extern int foo;
.cpp文件位于以下位置:
int foo;
等一下……你有
static int height = 0;
static int width = 0;
在头文件中,将在包含报头的每个编译单元中创建文件范围<代码>静态< /代码> s。如果您想使用全局变量,则在标头中声明为“代码>外部”/代码>,并将它们定义在一个编译单元中。 < P>我认为您误解了关键字<代码>静态< /代码>。C++中的这个键ord有很多含义,都是松散相关的
在顶层,而不是在类、结构或函数定义中,关键字<代码> static < /C> >创建一个奇怪的全局变量。该全局变量只能在它出现的“编译单元”中可见。“编译单元”的概念是由C++预处理器工作的方式创建的。
从 > < <代码>开始的所有内容都不是C++语言的一部分,而是预处理器的一部分。预处理器将所有这些指令和片段一起读入编译单元。它扩展了所有宏,并用指令中提到的文件内容替换了所有<代码> >包含指令。
,通过将> E>代码>选项传递给编译器,可以看到结果,这将显示编译C++程序时所得到的“编译单元”的内容。
您会注意到,所有包含的头文件都成为编译单元的一部分
现在,转到文件级静态变量
这些变量是编译单元的本地变量。如果在另一个编译单元中声明具有相同名称的文件级静态变量,则它们将是不同的变量。如果更改一个编译单元中的值,则它们与其他编译单元中这些变量的值无关
还记得头文件最终是如何被复制到每个编译单元中的吗
这意味着在头文件中声明的文件级静态变量在每个编译单元中都有副本。它们看起来是全局的,但实际上有许多非交互副本
在您的例子中,您可以通过使它们成为完全全局变量来轻松解决此问题。您可以使用头文件中的extern
关键字来完成此操作。这基本上会让编译器注意到全局变量以该名称存在。然后在一个特定的编译单元中将它们声明为非外部变量。然后,变量是giv编译编译单元产生的.o
文件中的en空格。因此基本上:
在foo.h
中:
extern int width;
extern int height;
在一些\u random.cpp
(但可能foo.cpp
):
编译单元的概念仅与文件级相关(不在类、结构或函数定义内)静态变量。在类、结构或函数定义中声明的静态变量遵循一些不同的规则。不知何故,一旦了解了< C++ >静态< /代码>中的每一个不同的规则,它们都被称为“代码> static < /COD>”是有意义的。将成员变量命名为width
和height
。如果您的注释为true,则这不是您正在运行的代码。您可能已经删除了重要的部分。方法aClass::Init()
有名为height/width的局部变量,或者类aClass
有名为height/width的成员。或者每个编译单元都有自己的height/width副本,main和aClass::Init在不同的编译单元中。我知道发生了什么,这个答案让我更加困惑。-1-1是的,它们应该是外部的,但是它们成为外部文件后不再是静态的。如果OP想要从多个文件访问它们,那么它们是静态的这一事实正是问题所在。
#include "foo.h"
int width = 0;
int height = 0;