Access static variable from CPP file to other header file

↘锁芯ラ 提交于 2021-01-16 04:17:27

问题


I'm trying to access the static variable in other header file from a CPP file.

"Boo.hpp"

#ifndef Boo_hpp
#define Boo_hpp

static int num;

class Boo
{
public:
    Boo()
    {
        num = 35;
    }
};

#endif /* Boo_hpp */

"Foo.hpp"

#ifndef Foo_hpp
#define Foo_hpp

class Foo
{
public:
    Foo();
};

#endif /* Foo_hpp */

"Foo.cpp"

#include "Foo.hpp"
#include "Boo.hpp"
#include <iostream>

Foo::Foo()
{
    std::cout << "Num : " << num << '\n';
}

"main.cpp"

#include <iostream>
#include "Foo.hpp"
#include "Boo.hpp"

int main()
{
    Boo boo;
    Foo foo;
}

The Result I get :

Num : 0
Program ended with exit code: 0

The Result I expect :

Num : 35
Program ended with exit code: 0

If I move the class Foo's constructor implementation from Foo.cpp to Foo.hpp, my code works as expected.

However, I would like to be able to access the num from Foo.cpp.

How should I fix my code?


回答1:


You need to understand two things to understand what is happening here.

  1. In C++, header files are just text which is "copy-pasted" to each .cpp file which includes them, directly or indirectly. The resulting preprosessed source code is "compilation unit", so you can basically think one .cpp file is one compilation unit.

  2. static global variables (not to be confused with static member variables of classes, AKA class variables, which are essentially same as non-static global variables...) are visible inside the compilation unit they are defined in. If you define static global variable in two compilation units, they are completely independent variables, and do not interfere (their names are not visible outside the compilation unit either). So, unless you know you do want separate copy of the variable in multiple .cpp files (very rare), you shouldn't put static global variables in .h file (extern declaration of global variable defined in a .cpp file is what you usually want in a .h file).

Now when you combine these two things, you realize that the static variable defined in .h file is no different from static variable defined in .cpp file. If .h file is included in several .cpp files, you get several copies of the variable, and which one is being used depends on which .cpp file it is (directly or through includes).

You have two .cpp files, which both define same static variable here, so they have two copies, and code compiled in these will use different variables.


Now there is extra quirk here. If you define a member function, including the constructor, inline (happens implicitly when you define it inside a class, if you define it in .h file but outside class you have to use the inline keyword), then every .cpp file will get a different copy of that function. Now you as programmer promise they will be the same, that is what inline means (it has only a little to do with inline optimization). If you have several copies of the same constructor (defined in a .h file), and they actually access different static variable, then they are not the same, and you break the promise. Don't do that!




回答2:


All translation units which includes the Boo.hpp will have their own definition of the num variable. No other TU (Translation Unit) will have the same num variable.

That's what the static linkage storage modifier means (for non-local, non-member variables).




回答3:


The keyword static on globals in C/C++ instructs the compiler to limit that symbol to the current compilation unit, i.e. the file it's declared in. Putting static declarations into header files is a huge trap because even though you include the same header in all your source files, each file will receive its own copy of the static symbol.

What you want is the extern keyword, that declares the symbol to be shared between compilation units, i.e. extern int num.

Some more reading on storage class specifiers here



来源:https://stackoverflow.com/questions/52025196/access-static-variable-from-cpp-file-to-other-header-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!