I know that having diamond inheritance is considered bad practice. However, I have 2 cases in which I feel that diamond inheritance could fit very nicely. I want to ask, wou
With out knowing more of what you are doing, I would probably reorganize things a bit. Instead of multiple inheritence with all these versions of action, I would make polymorphic reading and writing and writing classes, instanciated as delegates.
Something like the following (which has no diamond inheritence):
Here I present one of many ways implementing optional Delay, and assume the delay methodology is the same for all readers. each subclass might have their own implementation of delay in which case you would pass down to Read and instance of the respective derived Delay class.
class Action // abstract
{
// Reader and writer would be abstract classes (if not interfaces)
// from which you would derive to implement the specific
// read and write protocols.
class Reader // abstract
{
Class Delay {...};
Delay *optional_delay; // NULL when no delay
Reader (bool with_delay)
: optional_delay(with_delay ? new Delay() : NULL)
{};
....
};
class Writer {... }; // abstract
Reader *reader; // may be NULL if not a reader
Writer *writer; // may be NULL if not a writer
Action (Reader *_reader, Writer *_writer)
: reader(_reader)
, writer(_writer)
{};
void read()
{ if (reader) reader->read(); }
void write()
{ if (writer) writer->write(); }
};
Class Flow : public Action
{
// Here you would likely have enhanced version
// of read and write specific that implements Flow behaviour
// That would be comment to FlowA and FlowB
class Reader : public Action::Reader {...}
class Writer : public Action::Writer {...}
// for Reader and W
Flow (Reader *_reader, Writer *_writer)
: Action(_reader,_writer)
, writer(_writer)
{};
};
class FlowA :public Flow // concrete
{
class Reader : public Flow::Reader {...} // concrete
// The full implementation for reading A flows
// Apparently flow A has no write ability
FlowA(bool with_delay)
: Flow (new FlowA::Reader(with_delay),NULL) // NULL indicates is not a writer
{};
};
class FlowB : public Flow // concrete
{
class Reader : public Flow::Reader {...} // concrete
// The full implementation for reading B flows
// Apparently flow B has no write ability
FlowB(bool with_delay)
: Flow (new FlowB::Reader(with_delay),NULL) // NULL indicates is not a writer
{};
};