Zac*_*Lee 0 c++ static-linking
我正在尝试从CPP文件访问其他头文件中的静态变量。
Boo.hpp”#ifndef Boo_hpp
#define Boo_hpp
static int num;
class Boo
{
public:
Boo()
{
num = 35;
}
};
#endif /* Boo_hpp */
Run Code Online (Sandbox Code Playgroud)
Foo.hpp”#ifndef Foo_hpp
#define Foo_hpp
class Foo
{
public:
Foo();
};
#endif /* Foo_hpp */
Run Code Online (Sandbox Code Playgroud)
Foo.cpp”#include "Foo.hpp"
#include "Boo.hpp"
#include <iostream>
Foo::Foo()
{
std::cout << "Num : " << num << '\n';
}
Run Code Online (Sandbox Code Playgroud)
main.cpp”#include <iostream>
#include "Foo.hpp"
#include "Boo.hpp"
int main()
{
Boo boo;
Foo foo;
}
Run Code Online (Sandbox Code Playgroud)
我得到的结果:
Num : 0
Program ended with exit code: 0
Run Code Online (Sandbox Code Playgroud)
我期望的结果:
Num : 35
Program ended with exit code: 0
Run Code Online (Sandbox Code Playgroud)
如果将类Foo的构造函数实现从Foo.cpp移到Foo.hpp,我的代码将按预期工作。
不过,我想能够访问num从Foo.cpp。
我应该如何修正我的代码?
您需要了解两件事,以了解此处发生的情况。
在C ++中,头文件只是直接或间接“复制粘贴”到每个包含它们的.cpp文件的文本。由此产生的预先编写的源代码是“编译单元”,因此您基本上可以将一个.cpp文件视为一个编译单元。
static全局变量(不要与类的静态成员变量,AKA类变量(与非静态全局变量基本相同...)混淆)在定义它们的编译单元内部可见。两个编译单元,它们是完全独立的变量,并且不会相互干扰(它们的名称在编译单元外部也不可见)。因此,除非您知道确实要在多个.cpp文件中单独存储变量副本(非常罕见),否则不应该将静态全局变量放在.h文件中(extern通常,在.cpp文件中定义的全局变量声明是想要在.h文件中)。
现在,当您将这两件事结合在一起时,您将意识到.h文件中定义的静态变量与.cpp文件中定义的静态变量没有什么不同。如果.h文件包含在多个.cpp文件中,则将获得该变量的多个副本,并且使用哪个变量取决于它是哪个.cpp文件(直接或通过包含)。
您有两个.cpp文件,这两个文件都在此处定义了相同的静态变量,因此它们具有两个副本,并且在这些文件中编译的代码将使用不同的变量。
现在这里有个额外的怪癖。如果您定义一个成员函数,包括构造函数,则是内联的(在类内部定义时隐式发生,如果在.h文件中定义它,但在类外部则必须使用inline关键字),则每个.cpp文件都会得到一个该功能的不同副本。现在,作为程序员,您保证它们将是相同的,这就是什么inline意思(与内联优化几乎没有关系)。如果您具有同一构造函数的多个副本(在.h文件中定义),并且它们实际上访问了不同的静态变量,则它们是不相同的,您将无法兑现承诺。不要那样做!
| 归档时间: |
|
| 查看次数: |
609 次 |
| 最近记录: |