Handling multiple states in a C ++ class

What would be the most efficient and modern way to handle states in a C ++ class? At the moment I am using several bools, but the more I claim, I add that it is more difficult to maintain. For example, if I have a class called VideoPlayer and it has four bools defining different states. If we add the specified methods for each bool, we need to disable all the other bools.

class VideoPlayer
{

public:
    void play()
    {
        play_ = true;
        pause_ = false;
        stop_ = false;
        reset_ = false;
    }

    void stop()
    {
        stop_ = true;
        play_ = false;
        pause_ = false;
        reset_ = false;
    }

private:
    bool play_;
    bool pause_;
    bool stop_;
    bool reset_;
};
+4
source share
2 answers

Your design suffers from the fact that it is easy to be in poor condition (for example, that, if both stop_and play_are true?

enum , 1 .

++ enum Swift, Java # enum: - , #define.

++ 11 enum class, # enum. , Java Swift enum s.

- :

enum class PlayerState {
    Stopped,
    Playing,
    Paused
}

Reset , , enum.

class VideoPlayer {
private:
    PlayerState state;
public:
    VideoPlayer() :
        state( PlayerState::Stopped )
    {

    }

    void play() {

        switch( this->state ) {
            case PlayerState::Stopped:
                 // start video here, only change `state` when complete.
                // you might want to add a "BeginPlaying" (e.g. `LoadingFileFromDisk`) state value too.
                this->state = PlayerState.Playing;
                break;
            case PlayerState::Playing:
                throw VideoPlayerStateExeception("Already playing");
            case PlayerState::Paused:
                this->resume();
                break;
        }
    }


}
+8

++ 17 std::variant. .

struct Playing {
    float time_from_start;
};

struct Paused {
    float time_from_start;
};

struct Stopped {};

struct MediaPlayer {
    std::variant<
        Playing,
        Paused,
        Stopped
    > state;

    void play() {
        state = Playing{};
    }

    void pause() {
        state.visit([&](auto&& s){
            using S = std::decay_t<decltype(s)>;

            float time = 0;

            if constexpr (std::is_same_v<S, Playing>) {
                time = s.time_from_start;
            }

            state = Paused{time};
        });
    }
};

:

struct ABLoop {
    float a, b, time_from_a;
};
0

Source: https://habr.com/ru/post/1661647/


All Articles