Home > OS >  Abstract class selectively expose methods based on derived type
Abstract class selectively expose methods based on derived type

Time:06-12

I am writing an program that implements a factory TimeManager to generate two types of objects; a Timer and a StopWatch. Both of these objects are derived from an abstract class TimePiece, and share common methods. I would like the factory to return type TimePiece, but because Timer implements extra methods, I cant. How can I make TimePiece expose Timer's extra methods without exposing them to StopWatch when those respective types are created? I hope this makes sense, as it is a little hard to explain.

TimeManager.h

enum TimePieceType{TIMER, STOP_WATCH};

class TimeManager {
public:
    TimeManager();
    ~TimeManager();

    void Tick();
    TimePiece* AddTimePiece(TimePieceType timeType);
};

TimePiece.h

enum RunningState { STOPPED, RUNNING, PAUSED };

class TimePiece {
private:
    unsigned long startTime = 0;
    unsigned long currentTime = 0;
    unsigned long pauseOffset = 0;

protected:
    Time time;
    RunningState state = STOPPED;

public:
    TimePiece() = default;
    virtual ~TimePiece() = default;

    void Stop();
    void Start();
    void Pause();
    void Resume();
    void Reset();
    virtual void Tick();

    Time GetTime();
    RunningState GetState();
    virtual uint8_t GetId() = 0;
};

StopWatch.h

class StopWatch : public TimePiece {
private:
    uint8_t watchId = 0;
    static int8_t currentId;
    
public:
    StopWatch();
    virtual ~StopWatch();

    uint8_t GetId();
};

Timer.h

class Timer : public TimePiece {
private:
    uint8_t timerId = 0;
    static int8_t currentId;
    unsigned long timeout;

public:
    Timer();
    ~Timer();

    void Tick() override;

    void SetTimeoutMs(unsigned long timeout);
    void SetTimeoutSec(unsigned long timeout);

    uint8_t GetId();
    Time GetRemainingTime();
    unsigned long GetTimeout();
};

CodePudding user response:

You should not return TimePiece* because the two subclasses are sharing TimePiece for its implementation, not for its interface.

A simple approach is to give TimeManager two separate methods:

Timer* AddTimer();
StopWatch* AddStopWatch();

You can exploit polymorphic behavior if you need the Remove method:

void RemoveTimePiece(TimePiece*);
  • Related