调用 class 时跟踪布尔变量

Keep track of boolean variable when class is called

我有一个名为 Colorblind 的 class,它有 getter 和 setter 方法用于布尔变量 bool toggleColorBlind = false。我还有多个其他 classes,例如 Menu,用户可以切换布尔变量并将其设置为 true。

当我尝试从另一个 class 获取变量时,例如 Game,当我实例化 class 并使用 [=18] 时,布尔变量重置为其初始值=] class.

中的方法

当实例化和使用 class 时,如何防止布尔值重置为其初始值并跟踪它?可以通过使用 static 或其他方式更好地完成吗?

代码示例:

#include "Colorblind.h"

bool Colorblind::getToggleColorBlind()
{
    return mToggleColorBlind;
}

void Colorblind::setToggleColorBlind(bool state)
{
    mToggleColorBlind = state;
}
class Colorblind
{
public:
    Colorblind();

    bool toggleColorBlind(){return mToggleColor;}
    bool getToggleColorBlind();
    void setToggleColorBlind(bool state);

private:
    bool mToggleColorBlind = false;
};

现在用户可以在菜单中 enable/disable 色盲模式,它按预期工作。

Colorblind colorblind;

while (std::getline(cin, command)) {
    if (command == "toggle colorblind") {
       bool isToggled = colorblind.getToggleColorBlind();
       if (isToggled == true) {
          colorblind.setToggleColorBlind(false);
       } else {
          colorblind.setToggleColorBlind(true);
       }
    {
}

现在我的问题是,当我尝试通过从任何 class(例如 Game 中执行 Colorblind colorblind; colorblind.getToggleColorBlind() 来设置颜色等来访问 mToggleColorBlind 时。值是丢了,我怎么能跟踪这个。

您的目标是:“使 classes 的多个实例访问 Option 的单个实例”。

大多数时候有两种方式:

  1. 依赖注入:使 Option class 可供所有其他实例访问
  2. 使 Option class 成为全局单例。
    最好不要这样做,因为它会使您的代码难以模拟和测试。

全局单例的弊端

  • 很难解耦代码
  • 当代码变得更复杂时,您可能需要解决循环初始化问题。

我将提供 #1 的示例,如果您真的想要全局单调,this 可能会有所帮助。

Live Demo

#include <iostream>
#include "fmt/core.h"
class Option{
public:
    bool colorBlind() const {return mColorBlind;}
    void setColorBlind(bool enable){ mColorBlind = enable;}
private:
    bool mColorBlind = false;
};

class Game{
public:
    Game(Option& option): mOption(option){}

    void foo(){
        fmt::print("colorblind {}\n", mOption.colorBlind() );
    }
private:
    Option& mOption;
};

int main() {

    Option option;
    Game game{option};
    game.foo();
    option.setColorBlind(true);
    game.foo();
    return 0;
}

如果您的目标是在 MenuGame 等不同 class 的所有实例中共享相同的 toggleColorBlind,那么您可以使 toggleColorBlind一个静态数据成员,如下所示。将其设为静态数据成员将允许您在没有任何 ColorBlind 实例的情况下使用它。这是因为静态数据成员不与对应的 class ColorBlind.

的任何对象相关联

C++17

这里我们对静态数据成员使用inline关键字。

class ColorBlind 
{
    public:
      inline static bool toggleColorBlind = false;
    //^^^^^^ ^^^^^^------------------------------------->note inline and static used here
};
class Menu 
{   public:
    //method that toggles 
    void invertColorBlind() const 
    {
        ColorBlind::toggleColorBlind = !ColorBlind::toggleColorBlind;
        std::cout<<"changed to: "<<ColorBlind::toggleColorBlind<<std::endl;
    }
};
class Game 
{
    public:
       void invertColorBlind() const 
       {
           ColorBlind::toggleColorBlind = !ColorBlind::toggleColorBlind;
           std::cout<<"changed to: "<<ColorBlind::toggleColorBlind<<std::endl;
       }
};
int main()
{
    std::cout<<"Initially toggleColorBlind is: "<<ColorBlind::toggleColorBlind<<std::endl;  //prints 0
    
    Menu m;
    //lets change toggleColorBlind using an instance of Menu
    m.invertColorBlind();                 //prints 1
    
    //toggle again 
    m.invertColorBlind();                //prints 0
    
    Game g; 
    
    //lets change toggleColorBlind using an instance of Game 
    g.invertColorBlind();               //print 1
    
}

程序输出可见here:

Initially toggleColorBlind is: 0
changed to: 1
changed to: 0
changed to: 1

C++11

在 C++17 之前,我们不能在 class 中定义静态数据成员时使用 inline。所以这里我们将为静态数据成员提供一个out-of-class定义。

class ColorBlind 
{
    public:
      static bool toggleColorBlind;;
    //^^^^^^------------------------------------->note only the static used here
};

//define it outside class
bool ColorBlind::toggleColorBlind = false;

Working demo