简体   繁体   中英

How to set a flag properly

I have a timer class, inside the class there is a flag. When we did not call init(), flag is 0. After we call init(), it will be set to 1. After we call end(), it will be set back to 0.

class TimerHao
{
 private:
    double seconds;
    int    flag=0;  //0: Have not start accumulation. 1: In accumulation, between init() and end();

 public:

    void init();
    void end();
};

void TimerHao::init() 
{
    if(flag!=0) { throw runtime_error( "ERROR!!! Cannot initial the timer before it is ended!" ); }
    ...
    flag=1;
}

void TimerHao::end()
{
    if(flag!=1) { throw runtime_error("ERROR!!! Cannot end the timer before it is initialized!");}
    ...
    flag=0;
}

I can use the code by:

 TimerHao timerhao;
 timerhao.init();
 ...
 timerhao.end();
 ...
 timerhao.init();
 ...
 timerhao.end();
 ...

I do not like to set flag to a integer number, I need to read the comment to understand its meaning. Actually, I use this type of flag a lot in my code, eg flag can be 0, 1, 2, 3, 5, each number means different things. Sometimes, I get confused about my own code, I have to read comments carefully to understand what I am doing. Is there a clear way to handle this flag? Thank you.

You can add an enumeration and use that value in your code so the code is self-explanatory:

class TimerHao
{
 private:

    enum flag_states
    {
        FLAG_STATE_NOT_STARTED = 0,
        FLAG_STATE_IN_ACCUMULATION,
        // etc
    };

    double seconds;
    flag_states flag = FLAG_STATE_NOT_STARTED;  //0: Have not start accumulation. 1: In accumulation, between init() and end();

 public:

    void init();
    void end();
};

void TimerHao::init() 
{
    if(flag != FLAG_STATE_NOT_STARTED) { throw runtime_error( "ERROR!!! Cannot initial the timer before it is ended!" ); }

    flag = FLAG_STATE_IN_ACCUMULATION;
}

void TimerHao::end()
{
    if(flag != FLAG_STATE_IN_ACCUMULATION) { throw runtime_error("ERROR!!! Cannot end the timer before it is initialized!");}

    flag= FLAG_STATE_NOT_STARTED;
}

If you have access to C++11 you can even make it a scoped enumeration and disallow casting:

class TimerHao
{
 private:

    enum class flag_states
    {
        FLAG_STATE_NOT_STARTED = 0,
        FLAG_STATE_IN_ACCUMULATION,
        // etc
    };

    double seconds;
    flag_states flag = flag_states::FLAG_STATE_NOT_STARTED;  //0: Have not start accumulation. 1: In accumulation, between init() and end();

 public:

    void init();
    void end();
};

void TimerHao::init() 
{
    if(flag != flag_states::FLAG_STATE_NOT_STARTED) { throw runtime_error( "ERROR!!! Cannot initial the timer before it is ended!" ); }

    flag = flag_states::FLAG_STATE_IN_ACCUMULATION;
}

void TimerHao::end()
{
    if(flag != flag_states::FLAG_STATE_IN_ACCUMULATION) { throw runtime_error("ERROR!!! Cannot end the timer before it is initialized!");}

    flag= flag_states::FLAG_STATE_NOT_STARTED;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM