简体   繁体   English

从 CPP 文件访问静态变量到其他头文件

[英]Access static variable from CPP file to other header file

I'm trying to access the static variable in other header file from a CPP file.我正在尝试从 CPP 文件访问其他头文件中的静态变量。

" Boo.hpp " Boo.hpp

#ifndef Boo_hpp
#define Boo_hpp

static int num;

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

#endif /* Boo_hpp */

" Foo.hpp " Foo.hpp

#ifndef Foo_hpp
#define Foo_hpp

class Foo
{
public:
    Foo();
};

#endif /* Foo_hpp */

" Foo.cpp " Foo.cpp

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

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

" main.cpp " 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.如果我将类Foo的构造函数实现从Foo.cppFoo.hpp ,我的代码会按预期工作。

However, I would like to be able to access the num from Foo.cpp .但是,我希望能够从Foo.cpp访问num

How should I fix my code?我应该如何修复我的代码?

All translation units which includes the Boo.hpp will have their own definition of the num variable.所有包含Boo.hpp 翻译单元都有自己num变量定义。 No other TU (Translation Unit) will have the same num variable.没有其他 TU(翻译单元)将具有相同的num变量。

That's what the static linkage storage modifier means (for non-local, non-member variables).这就是static 链接存储修饰符的含义(对于非局部、非成员变量)。

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.在 C++ 中,头文件只是直接或间接“复制粘贴”到每个包含它们的 .cpp 文件的文本。 The resulting preprosessed source code is "compilation unit", so you can basically think one .cpp file is one compilation unit.生成的预处理源代码是“编译单元”,所以基本上可以认为一个.cpp文件就是一个编译单元。

  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). static全局变量(不要与类的静态成员变量混淆,AKA 类变量,本质上与非静态全局变量相同...)在定义它们的编译单元内是可见的。如果定义静态全局变量在两个编译单元中,它们是完全独立的变量,互不干扰(它们的名称在编译单元之外也不可见)。 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).因此,除非您知道您确实希望在多个 .cpp 文件中单独复制变量(非常罕见),否则您不应将静态全局变量放在 .h 文件中(在 .cpp 文件中定义的全局变量的extern声明是您所需要的)通常需要在 .h 文件中)。

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.现在当你把这两个东西结合起来时,你会发现 .h 文件中定义的静态变量与 .cpp 文件中定义的静态变量没有什么不同。 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).如果 .h 文件包含在多个 .cpp 文件中,您将获得该变量的多个副本,使用哪个副本取决于它是哪个 .cpp 文件(直接或通过包含)。

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.您有两个 .cpp 文件,它们都在这里定义了相同的静态变量,因此它们有两个副本,并且在这些文件中编译的代码将使用不同的变量。


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.如果你定义一个成员函数,包括构造函数,内联(当你在类内部定义它时隐式发生,如果你在 .h 文件中定义它但在类外部你必须使用inline关键字),那么每个 .cpp 文件都会得到该函数的不同副本。 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).现在你作为程序员承诺它们将是相同的,这就是inline意思(它与内联优化只有一点关系)。 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.如果您有多个相同构造函数的副本(在 .h 文件中定义),并且它们实际上访问不同的静态变量,则它们不相同,并且您违反了承诺。 Don't do that!不要那样做!

The keyword static on globals in C/C++ instructs the compiler to limit that symbol to the current compilation unit, ie 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. C/C++ 中全局变量上的关键字static指示编译器将该符号限制为当前编译单元,即声明它的文件。将static声明放入头文件是一个巨大的陷阱,因为即使您在所有源文件,每个文件都会收到自己的静态符号副本。

What you want is the extern keyword, that declares the symbol to be shared between compilation units, ie extern int num .您想要的是extern关键字,它声明要在编译单元之间共享的符号,即extern int num

Some more reading on storage class specifiers here此处阅读有关存储类说明符的更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM