如何在C ++中使用公共静态变量

时间:2019-09-06 00:20:10

标签: c++ static

似乎没有一个清晰,简洁的示例,可以从StackOverflow上的多个文件中真正地使用C ++中的公共静态变量。

有许多示例说明了如何在单个C ++转换单元中使用静态变量,以及有关static关键字的各种用法的确切性质的许多问题,但是作为一个对C#更有经验的程序员,我发现很难抓就像在C#或Java中一样,我只需要简单地“在一个类上有一个静态变量并在其他地方使用它”即可。

在这里,我将尝试以最直接的方式展示我发现的内容。我希望其他人可以改善答案,并为感兴趣的人提供更多技术细节。

SomeClass.h

在要具有静态变量的类的头文件中,我们只需像在C#或Java中那样将其声明为静态即可。不要在这里尝试初始化变量; C ++不喜欢这样。

class SomeClass
{
public:
  static bool some_flag;
};

SomeClass.cpp

在该类的cpp文件中,我们为静态变量创建存储,就像我们将为成员函数提供实现一样。在这里我们可以初始化变量。到目前为止,一切进展顺利!

#include "SomeClass.h"

bool SomeClass::some_flag = true;

SomeOtherClass.cpp

这是我遇到问题的地方。如果我们尝试从其他地方访问SomeClass::some_flag(首先面对的可能是您想要公共静态变量的原因),则链接器将抱怨它不知道它在哪里。我们已经告诉编译器静态变量存在,因此编译器很高兴。问题在于,在另一个翻译单元中,我们从未指定静态变量的存储位置。您可能会尝试尝试重新声明存储,并希望链接程序将它们都解析为“我在some_flag中声明的SomeClass.h”,但事实并非如此。它会抱怨您给了变量两个家,这当然不是您的意思。

我们需要做的是告诉链接器some_flag的存储位于其他位置,并且在我们尝试在链接时将所有翻译单元放在一起时,就会找到它。为此,我们使用extern关键字。

#include "SomeOtherClass.h"
#include "SomeClass.h"

extern bool SomeClass::some_flag;

void SomeOtherClass::SomeOtherFunction()
{
  SomeClass::some_flag = true;
};

Voila!编译器很高兴,链接器很高兴,希望程序员也很高兴。

我现在公开讨论我不应该使用公共变量,应该刚刚通过SomeClass实例通过介于其和用法之间的87层代码传递,应该使用C ++ 23中的某些功能,应该使用boost::obscurething等,等等。

但是,我确实欢迎针对此基本问题的任何替代方法,这些方法与我在此演示的用法相同。

2 个答案:

答案 0 :(得分:2)

  

这是我遇到问题的地方。如果我们尝试仅从其他位置访问SomeClass :: some_flag,则链接器将抱怨它不知道它住在哪里。

只要您与定义变量(SomeClass.cpp)的翻译单元链接,链接器就不会抱怨。

extern bool SomeClass::some_flag;

此声明既不被允许,也不是必需的。包含变量声明的类定义对于编译器而言已足够,SomeClass.cpp中的变量定义对于链接器而言已足够。 Demo

  

不要在这里尝试初始化变量; C ++不喜欢这样。

     

但是,我确实欢迎任何其他解决此基本问题的方法

您可以简单地使用内联变量(自C ++ 17起):

class SomeClass
{
public:
    inline static bool some_flag = true;

答案 1 :(得分:-3)

对于那些只想要代码以便他们可以重新开始工作的人们来说,答案为摘要形式:

SomeClass.h

#pragma once

class SomeClass
{
public:
  static bool some_flag;
};

SomeClass.cpp

#include "SomeClass.h"

bool SomeClass::some_flag = true;

SomeOtherClass.cpp

#include "SomeOtherClass.h"
#include "SomeClass.h"

extern bool SomeClass::some_flag;

void SomeOtherClass::SomeOtherFunction()
{
  SomeClass::some_flag = true;
}