Home > Enterprise >  Keep track of boolean variable when class is called
Keep track of boolean variable when class is called

Time:05-31

I have a class named Colorblind which has getter and setter methods for a boolean variable called bool toggleColorBlind = false. I have multiple other classes such as Menu which a user can toggle the boolean variable and set it to true.

When I try to get the variable from another class, like Game, the boolean variable resets to its initial value when I instantiate the class and use the getToggleColorBlind() method within the class.

What can I do to prevent the boolean from resetting to its initial value and keep track of it when the class is instantiated and used? Could this be done a better way by using static or something?

Code example:

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

Now the Menu is where a user can enable/disable colorblind mode which works as expected.

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

Now my problem is when I try to access the mToggleColorBlind by doing Colorblind colorblind; colorblind.getToggleColorBlind() from any class such as Game to set colors etc.. The value is lost, how can I keep track of this.

CodePudding user response:

If you goal is to share the same toggleColorBlind across all the instance of different classes like Menu and Game, then you can make toggleColorBlind a static data member as shown below. Making it a static data member would allow you use it without any instance of ColorBlind. This is because a static data member is not associated with any object of the corresponding class ColorBlind.

C 17

Here we use inline keyword for static data member.

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
    
}

The output of the program can be seen here:

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

C 11

Prior to C 17, we could not use inline while defining a static data member inside class. So here we will provide an out-of-class definition for the static data member.

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

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

Working demo

CodePudding user response:

You goal is : "Making multiple instances of classes accessing to a single instance of Option".

Most of time there are two ways:

  1. Dependency Injection: Make Option class accessible to all other instance
  2. Make Option class a global singleton.
    Better not to do it, because it makes your code hard to mock and test.

The draback of global singleton

  • Hard to decouple the code
  • You might need to resolve circular initialization issue when code gets more complex.

I will provide an example of #1, and if you really want global singletone, this might help.

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

  • Related