对静态变量的更改超出范围?(C++)

changes to static variable goes out of scope? (C++)

本文关键字:范围 C++ 变量 静态      更新时间:2023-10-16

我有一个包含静态变量的头文件,例如窗口宽度和高度。

我通过 XML 文件读取这些变量的新值,但是一旦更改了这些更改的函数超出范围,这些更改似乎就不会被注册。

举例说明:

// 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()
}  

等一下...你有

static int height = 0;
static int width = 0;

在头文件中? 这将在包含标头的每个编译单元中创建文件范围的static。 如果要使用全局变量,请在标头中将它们声明为 extern,并在一个编译单元中定义它们。

如果你没有在某处将静态声明为 extern,你最终得到的实际上是每个编译单元的多个静态副本(同名)。

正确的示例:

测试.h

extern int mystatic;

测试.cpp

int mystatic = 0;
void myFunction() // or member funciton, who cares
{
    mystatic = 42;
}

主.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;
 }

你应该在头文件中声明静态变量,extern ed并在 cpp 文件中定义它们。

.h 文件:

extern int foo;

.cpp某处的文件:

int foo;

我认为

您误解了关键字static.在C++这个关键字有很多含义,都是松散相关的。

在顶层,而不是在类、结构或函数定义中,关键字 static 创建一种奇怪的全局变量。该全局变量仅在它出现的"编译单元"中可见。"编译单元"的想法是通过C++预处理器的工作方式创建的。

所有以#开头的东西都不是C++语言的一部分,而是预处理器的一部分。预处理器读取所有这些指令并将编译单元拼凑在一起。它扩展所有宏,并将所有#include指令替换为指令中提到的文件内容。

使用 gcc,您可以通过将 -E 选项传递给编译器来查看此结果。这将在编译C++文件时显示生成的"编译单元"的内容。

您会注意到,所有#include ed 头文件都成为编译单元的一部分。

现在,转到文件级静态变量...

这些变量是编译单元的局部变量。如果在另一个编译单元中声明具有相同名称的文件级静态变量,则它们将是不同的变量。如果更改一个编译单元中的值,则它们与其他编译单元中的这些变量的值无关。

还记得头文件最终是如何被复制到每个编译单元中的吗?

这意味着在头文件中声明的文件级静态变量最终在每个编译单元中都有副本。它们看似是全球性的,但实际上会有许多非交互的副本。

在您的情况下,您可以通过使它们完全全局化来轻松解决此问题。您可以使用头文件中的 extern 关键字执行此操作。这基本上使编译器注意到存在具有该名称的全局变量。然后,在一个特定的编译单元中将它们声明为非外部。然后,在编译该编译单元产生的.o文件中为变量提供空间。所以基本上:

foo.h

extern int width;
extern int height;

some_random.cpp(但可能是foo.cpp):

#include "foo.h"
int width = 0;
int height = 0;

编译单元的概念仅与文件级(不在类、结构或函数定义内部)静态变量相关。在类、结构或函数定义中声明的静态变量遵循一些不同的规则。不知何故,一旦您了解了static的每个不同规则,它们都被称为 static 真的很有意义。:-)