将静态变量从CPP文件访问到其他头文件 [英] Access static variable from CPP file to other header file

查看:60
本文介绍了将静态变量从CPP文件访问到其他头文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从CPP文件访问其他头文件中的静态变量.

" Boo.hpp "

  #ifndef Boo_hpp#define Boo_hpp静态整数嘘{上市:Boo(){num = 35;}};#endif/* Boo_hpp */ 

" Foo.hpp "

  #ifndef Foo_hpp#定义Foo_hppFoo类{上市:Foo();};#endif/* Foo_hpp */ 

" Foo.cpp "

  #include"Foo.hpp"#include"Boo.hpp"#include< iostream>Foo :: Foo(){std :: cout<<数字:"<<num<<'\ n';} 

" main.cpp "

  #include< iostream>#include"Foo.hpp"#include"Boo.hpp"int main(){Boo boo;Foo foo;} 

我得到的结果:

 数字:0程序以退出代码结束:0 

我期望的结果:

 数字:35程序以退出代码结束:0 

如果将类 Foo 的构造函数实现从 Foo.cpp 移到 Foo.hpp ,我的代码将按预期工作./p>

但是,我希望能够从 Foo.cpp 访问 num .

我应该如何修正我的代码?

解决方案

您需要了解两件事,以了解此处发生的情况.

  1. 在C ++中,头文件只是直接或间接复制粘贴"到每个包含它们的.cpp文件的文本.由此产生的预先准备好的源代码为编译单元",因此您基本上可以将一个.cpp文件视为一个编译单元.

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

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

您有两个.cpp文件,这两个文件都在此处定义了相同的静态变量,因此它们具有两个副本,并且在这些文件中编译的代码将使用不同的变量.


现在这里有个额外的怪癖.如果您定义一个成员函数(包括构造函数),则是内联的(在类内部对其进行定义时会隐式发生,如果在.h文件中但在类外部进行定义,则必须使用 inline 关键字),那么每个.cpp文件都会获得该函数的不同副本.现在,作为程序员,您保证它们将是相同的,这就是 inline 的含义(与内联优化几乎没有关系).如果您具有同一构造函数的多个副本(在.h文件中定义),并且它们实际上访问了 different 静态变量,则它们是不相同的,您就无法兑现.不要那样做!

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?

解决方案

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!

这篇关于将静态变量从CPP文件访问到其他头文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆