I have a class Channel with two two properties, direction and size which are fixed during construction. Direction can take only one of two values, forward (1) or backward(-1). Size can take any value, but there is a physically meaningful distinction between 0 and any nonzero value.
I'd like to be able to write functions that accept Channel objects with known values for the direction and/or size, and I thought to implement this using derived classes:
Channel
|
-----------------------------------------------
| | | |
ForwardChannel BackwardChannel ZeroChannel NonzeroChannel
| | | |
| ---------------- ...
| | |
| BackwardZeroChannel |
| |
---------------------------------
|
ForwardZeroChannel
Obviously I didn't draw all of the permutations.
I tried implementing it as so
class Channel {
Channel(int direction, int size) { ... };
...
}
class ForwardChannel: public virtual Channel {
ForwardChannel(int size) : Channel(1, size) { ... }
...
}
class ZeroChannel: public virtual Channel {
ZeroChannel(int direction) : Channel(direction, 0) { ... }
...
}
class ForwardZeroChannel: public ForwardChannel, ZeroChannel {
ForwardZeroChannel() : ForwardChannel(0), ZeroChannel(1)
...
}
Instantiating ForwardChannel and ZeroChannel works fine. Instantiating ForwardZeroChannel calls only the default constructor for Channel which doesn't set the values. I have to add Channel(1, 0) to the initializer list:
class ForwardZeroChannel: public ForwardChannel, ZeroChannel {
ForwardZeroChannel() : Channel(0, 1), ForwardChannel(0), ZeroChannel(1)
...
}
but that seems to defeat some of the purpose of deriving from ForwardChannel and ZeroChannel. Is there a better way of doing this?
what about (following need c++11, but it could be ported to c++99 (except the 'template using') ):