changes to static variable goes out of scope? (C++)
I have a header file containing static variables, such as window width and height.
I read new values for these variables through a XML file, but these changes does not seem to be registered once the function it was changed in, goes out of scope.
Example to illustrate:
// These are in a separate h开发者_C百科eader 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()
}
Wait a minute ... you have
static int height = 0;
static int width = 0;
in a header file? That will create file-scoped static
s in each compilation unit that includes the header. If you want to use global variables, then declare them as extern
in the header and define them in one compilation unit.
If you don't declare a static as extern somewhere, what you'll end up with are actually multiple copies of statics (by the same name) per compilation unit.
Correct example:
test.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;
}
HTH
You should declare your static variables in a header file, extern
ed and define them in a cpp file.
.h file:
extern int foo;
.cpp file somewhere:
int foo;
I think you are misunderstanding the the keyword static
. In C++ this keyword has many meanings, all loosely related.
At the top level, not inside a class, struct or function definition, the keyword static
creates a weird sort of global variable. That global variable is only visible in the 'compilation unit' in which it appears. The idea of a 'compilation unit' is created by the way the C++ preprocessor works.
All of the stuff starting with #
are not part of the C++ language proper, but part of the preprocessor. The preprocessor reads all those directives and pieces together a compilation unit. It expands all of the macros, and replaces all the #include
directives with the contents of the file mentioned in the directive.
With gcc, you can see the result of this by passing the -E
option to the compiler. That will show you the contents of the resulting 'compilation unit' when you compile a C++ file.
You will notice that all of the #include
ed header files become part of the compilation unit.
Now, on to file-level static variables...
These variables are local to a compilation unit. If you declare file level static variables with the same name in another compilation unit, they will be different variables. If you alter the values in one compilation unit, they have no relation to the values of these variables in the other compilation units.
Remember how header files end up basically being copied into each compilation unit?
That means that file level static variables declared in header files end up having copies in each compilation unit. They will be seemingly global, but in fact will have many non-interacting copies.
In your case, you can easily solve this problem by making them fully global variables. You can do this using the extern
keyword in the header file. This basically puts the compiler on notice that global variables exist with that name. Then you declare them as non-extern in one particular compilation unit. The variables then are given space in the .o
file that results from compiling that compilation unit. So basically:
In foo.h
:
extern int width;
extern int height;
In some_random.cpp
(but probably foo.cpp
):
#include "foo.h"
int width = 0;
int height = 0;
The concept of a compilation unit is only relevant for file-level (not inside a class, struct or function definition) static variables. Static variables declared inside class, struct or function definitions obey some different rules. Somehow, once you understand each of the different rules for static
it really makes sense that they are all called static
. :-)
精彩评论