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

时间:2018-08-26 10:07:12

标签: c++ static-linking

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

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;
}

我得到的结果:

Num : 0
Program ended with exit code: 0

我期望的结果:

Num : 35
Program ended with exit code: 0

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

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

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

3 个答案:

答案 0 :(得分:4)

所有包含Boo.hpp的{​​{3}}都将对num变量具有它们自己的定义。没有其他TU(翻译单元)具有相同的num变量。

这就是static translation units的含义(对于非本地,非成员变量)。

答案 1 :(得分:4)

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

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

  2. <div id="one"></div> <div class="services"> <a> <div class="services-items"> <h2>Service 1</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Similique amet atque recusandae, consequatur facere nesciunt. Placeat nostrum, aliquam suscipit. Tempore obcaecati sed eligendi cumque! Quo et, quod veniam nulla maxime quos voluptas harum odio ipsam libero repellat dicta hic. Eos!</p> </div> </a> <a> <div class="services-items"> <h2>Service 2</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perferendis pariatur vitae illum, alias suscipit ipsa soluta optio eos officia ducimus incidunt maiores molestias velit, delectus libero, ad eaque repellendus. Rerum, rem doloribus, cupiditate quos ex hic porro distinctio beatae. Vero, harum, autem. Quo itaque assumenda, mollitia et repellendus vel porro.</p> </div> </a> <a> <div class="services-items"> <h2>Service 3</h2> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Praesentium error et animi, porro omnis facilis voluptatum vel voluptatem pariatur quasi debitis in ratione voluptas eos ex maiores adipisci, nesciunt aliquid alias maxime accusamus veritatis? Dignissimos, perspiciatis deserunt numquam animi rerum aliquid mollitia, blanditiis dolore architecto.</p> <h3>Jos haluat tämän palvelun/tuotteen, ota yhteyttä ja kerro viestissä.</h3> </div> </a> </div> <div id="two"></div>全局变量(不要与类的静态成员变量,AKA类变量(本质上与非静态全局变量相同)...)在编译单元内可见如果在两个编译单元中定义静态全局变量,则它们是完全独立的变量,并且不会相互干扰(它们的名称在编译单元外部也不可见)。因此,除非您知道确实要在多个.cpp文件中单独存储变量副本(非常罕见),否则不应该将静态全局变量放在.h文件中({.cpp中定义的全局变量的static声明文件是通常需要的.h文件)。

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

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


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

答案 2 :(得分:3)

在C / C ++中,全局变量上的关键字static指示编译器将该符号限制为 current 编译单元,即声明该符号的文件。放置static声明进入头文件是一个巨大的陷阱,因为即使您在所有源文件中都包含相同的头,每个文件仍会收到自己的静态符号副本。

您想要的是extern关键字,它声明要在编译单元之间共享的符号,即extern int num

有关存储类说明符here

的更多信息