liudr:
So maybe I don't need to call any method in base class since it's got no actual methods but anyway, any simple syntax to refer to a method in a base class if useful. Can I do this?
In derived class method, do this buttons.sense() to call the base class method, then do softwarebuttons.sense() to call the derived class method?
If you have a "button" object and you call "sense()", "button::sense()" will get called. If you have a "softwarebutton" and you call "sense()", "softwarebutton::sense()" will get called.
A virtual method is only useful if you expect to have a button POINTER that is in fact pointing to a softwarebutton;
softwarebutton swb;
button* pb = &swb;
pb->sense();
In this case, softwarebutton::sense() will get called on swb.
Having virtual methods on a base interface-style class is useful when you want to pass around pointers to the base class. It's probably easiest to give an example from something I use. I have an "Updated" base class. It's really simple:
class Updated
{
public:
virtual void update(void) = 0;
};
So anything which derives from "Updated" is something that I want to get updated every time through loop(), e.g.
class Siren: public Updated
{
... specific stuff to make a siren ...
public:
virtual void update(void) { ...update my siren... }
};
The key here is that I will pass a pointer to my_siren to a method that expects a pointer to an Updated.
class UpdateManager
{
... other stuff to manage a list of Updated*'s ...
public:
add(Updated* object) { ... add object to list of objects ... }
void updateAll(void) { ... run through list of objects and call 'update' on each ... }
};
Then, in a sketch...
Siren my_siren;
UpdateManager upm;
void setup()
{
upm.add(&my_siren);
}
void loop()
{
upm.updateAll();
}
This will cause my_siren.update() to get called, even though the UpdateManager has no idea about a 'Siren' specifically, it just knows about the 'Updated' interface.