首页 > 解决方案 > 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.

"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?

标签: c++static-linking

解决方案


您需要了解两件事才能了解这里发生的事情。

  1. 在 C++ 中,头文件只是直接或间接地“复制粘贴”到每个包含它们的 .cpp 文件的文本。生成的预处理源代码是“编译单元”,因此您基本上可以认为一个 .cpp 文件就是一个编译单元。

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

现在当你把这两件事结合起来时,你就会意识到.h文件中定义的静态变量与.cpp文件中定义的静态变量没有什么不同。如果 .h 文件包含在多个 .cpp 文件中,您将获得该变量的多个副本,而使用哪一个取决于它是哪个 .cpp 文件(直接或通过包含)。

你有两个 .cpp 文件,它们都在这里定义了相同的静态变量,所以它们有两个副本,在这些文件中编译的代码将使用不同的变量。


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


推荐阅读