c++ - 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++ 中,头文件只是直接或间接地“复制粘贴”到每个包含它们的 .cpp 文件的文本。生成的预处理源代码是“编译单元”,因此您基本上可以认为一个 .cpp 文件就是一个编译单元。
static
全局变量(不要与类的静态成员变量混淆,AKA 类变量,它们本质上与非静态全局变量相同......)在它们定义的编译单元内可见。如果您在其中定义静态全局变量两个编译单元,它们是完全独立的变量,互不干扰(它们的名称在编译单元之外也不可见)。所以,除非你知道你确实想要在多个 .cpp 文件中单独复制变量(非常罕见),否则你不应该将静态全局变量放在 .h 文件中(extern
在 .cpp 文件中定义的全局变量的声明通常是想要在 .h 文件中)。
现在当你把这两件事结合起来时,你就会意识到.h文件中定义的静态变量与.cpp文件中定义的静态变量没有什么不同。如果 .h 文件包含在多个 .cpp 文件中,您将获得该变量的多个副本,而使用哪一个取决于它是哪个 .cpp 文件(直接或通过包含)。
你有两个 .cpp 文件,它们都在这里定义了相同的静态变量,所以它们有两个副本,在这些文件中编译的代码将使用不同的变量。
现在这里有额外的怪癖。如果你定义一个成员函数,包括构造函数,内联(当你在一个类中定义它时隐式发生,如果你在 .h 文件中定义它但在类之外你必须使用inline
关键字),那么每个 .cpp 文件都会得到一个该功能的不同副本。现在你作为程序员承诺它们将是相同的,这就是inline
意思(它与内联优化只有一点关系)。如果您有多个相同构造函数的副本(在 .h 文件中定义),并且它们实际上访问不同的静态变量,那么它们就不一样,并且您违反了承诺。不要那样做!
推荐阅读
- asp.net - C# 应用程序在 VM 上运行良好,但在 docker 上运行良好
- scala - 在 spark 中查找每组最常见的非空前缀
- scsi - LTO 磁带上的预警在哪里?
- asp.net-core-webapi - 带有 Web Api 的 OrchardCore 多租户
- scala - 如何使用过滤器从scala中的数据框中获取包含空值的行集
- here-api - 此处 API 中的世代号
- javascript - JavaScriptClass:简单的条件(三元)运算符返回错误的结果
- xeus-cling - 如何用archiconda3安装xeus-cling?
- javascript - 遍历 javascript 嵌套对象
- ruby-on-rails - Active Record 在一个查询中计算多个连接表?