Header only derived classes and virtual functions

I have a Base class for relays and have been looking at creating children classes for the types of things that would be controlled by the Relays. At this time I can’t think of any implementation code differences between the Base and Child and at this time the main difference between Base and Children are the enums that provide a descriptive state of what happens when the relay is open or closed. Given that info and the code below…am I on the correct path here?

NOTE: I am fairly certain I don’t have my virtuals done properly…would it be just the Base class that has functions defined as Virtual (I think pure virtuals is the answer) and nothing for the children? Is there a way to have the Base class return Child enum types for further use in other parts of my app?

Base Class

typedef enum {
  RELAY_STATUS_OPEN = 0,
  RELAY_STATUS_CLOSED = 1
} relay_status_t;

class Pacsui_Relay
  {
    private:

    //Private functions

    //Private variables

    public:
    //Public functions
    Pacsui_Relay(void);
    virtual void begin(int pin);
    virtual relay_status_t on();
    virtual relay_status_t off();
    virtual relay_status_t getState();

    //Public variables
    relay_status_t relayStatus;

    protected:
    int _pin;
  };


#endif

Child

typedef enum heater_status_t {
  HEATER_STATUS_OFF = 0,
  HEATER_STATUS_ON = 1
} heater_status_t;

class Pacsui_Heater : public Pacsui_Relay
  {
    private:


    //Private functions

    //Private variables

    //Class Objects

    public:
    //Public functions
    Pacsui_Heater(void);
    virtual ~Pacsui_Heater();
    virtual void begin();
    virtual heater_status_t on();
    virtual heater_status_t off();

    //Public variables

  };
extern Pacsui_Heater heater;
#endif

In case anyone ever stumbles upon this I switched to an interface implementation (AKA “has-a”) versus “is-a”. Now the heater class contains a relay object instance for low level control via the functions exposed by the relay class and I can use device specific return types with no issue. No virtual functions needed…

If any of the smart people out there think this could be done more elegantly or efficiently please let me know, I want to do things the proper way.