This is our ideal inheritance hierarchy:
class Foobar;
class FoobarClient : Foobar;
class FoobarServer : Foobar;
class WindowsFoobar : Foobar;
class UnixFoobar : Foobar;
class WindowsFoobarClient : WindowsFoobar, FoobarClient;
class WindowsFoobarServer : WindowsFoobar, FoobarServer;
class UnixFoobarClient : UnixFoobar, FoobarClient;
class UnixFoobarServer : UnixFoobar, FoobarServer;
This is because the our inheritance hierarchy would try to inherit from Foobar
twice, and as such, the compiler would complain of ambiguous references on any members of Foobar
.
Allow me to explain why I want such a complex model. This is because we want to have the same variable accessible from WindowsFoobar
, UnixFoobar
, FoobarClient
, and FoobarServer
. This wouldn't be a problem, only I'd like to use multiple inheritance with any combination of the above, so that I can use a server/client function on any platform, and also use a platform function on either client or server.
I can't help but feel this is a somewhat common issue with multiple inheritance... Am I approaching this problem from completely the wrong angle?
Also, consider that we could use #ifdef
to get around this, however, this will tend to yield very ugly code like such:
CFoobar::CFoobar()
#if SYSAPI_WIN32
: m_someData(1234)
#endif
{
}
... yuck!
For those who want to read more into the background of this issue, I really suggest skimming over the appropriate mailing list thread. Thing start to get interesting around the 3rd post. Also there is a related code commit with which you can see the real life code in question here.
It would work, although you'd get two copies of the base Foobar
class. To get a single copy, you'd need to use virtual inheritance. Read on multiple inheritance here.
class Foobar;
class FoobarClient : virtual public Foobar;
class FoobarServer : virtual public Foobar;
class WindowsFoobar : virtual public Foobar;
class UnixFoobar : virtual public Foobar;
However, there are many problems associated with multiple inheritance. If you really want to have the model presented, why not make FoobarClient
and FoobarServer
take a reference to Foobar
at construction time, and then have Foobar& FoobarClient/Server::getFoobar
?
Composition is often a way out of multiple inheritance. Take a example now:
class WindowsFoobarClient : public WindowsFoobar
{
FoobarClient client;
public:
WindowsFoobarClient() : client( this ) {}
FoobarClient& getClient() { return client }
}
However care must be taken in using this in the constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With