I have an abstract class, called UsbDevice (mostly pure virtual). It doesn't do much, but the three derived classes do:
class WindowsUsbDevice : public UsbDevice
class LinuxUsbDevice : public UsbDevice
class OsxUsbDevice : public UsbDevice
each of these classes doesn't really add any public methods - instead they are just different implementations of the UsbDevice abstract class.
Now, I want to create a new class that derives from any one of these classes, let's call it FancyUsbDevice. Lets say it represents a specific device.
This new class needs to expose the full UsbDevice interface (implemented by the intermediate class), as well as expose a few fancy high-level functions that only use methods on the UsbDevice interface - no need to expose anything specific to one of those intermediate classes.
I can see three possible options, and I would like to know if they would work, and which one is the best.
A) don't inherit, instead make FancyUsbDevice HAS-A UsbDevice* instead of be IS-A. (sidestep the problem. I don't like this option, but it feels safe.)
B) Assuming I have the rare advantage of only having one of those classes actually build on any specific platform, #ifdef the inheritance string: (sidestep the problem again)
#ifdef WIN32
class FancyUsbDevice : public WindowsUsbDevice
#endif
#ifdef LINUX
class FancyUsbDevice : public LinuxUsbDevice
#endif
...
C) Templates! Inherit from the template type:
Template<typename T> class FancyUsbDevice : public T
construct it as the child type, and cast it to the interface:
FancyUsbDevice<WindowsUsbDevice> fancy_device;
FancyUsbDevice<UsbDevice> generic_fancy_device = dynamic_cast<FancyUsbDevice<UsbDevice>>(fancy_device);
however, I don't think that would work, for at least the reason that the compiler will think that generic_fancy_device is smaller than fancy_device, and all of the member variables will be offset and broken. (I think)
Thanks! Sorry for using interface / abstract / pure virtual interchangeably.