I have interface based on another:
class IDrawable {
public:
virtual ~IDrawable();
};
class IExtendedDrawable: public IDrawable {
public:
virtual ~IExtendedDrawable();
};
class DrawableImplementation: public IDrawable {
public:
virtual ~DrawableImplementation();
};
class ExtendedDrawableImplementation:
public DrawableImplementation, public IExtendedDrawable
{
public:
virtual ~ExtendedDrawableImplementation();
};
Then ExtendedDrawableImplementation = DrawableImplementation (+IDrawable) + IExtendedDrawable (+IDrawable)
Is it right to have IDrawable twice in same class?
I'll give the benefit of the doubt that you DO indeed need/want multiple inheritance. I see it as good in only limited situations, and interfaces is one of them (even Java allows this).
As said above, use virtual inheritance and be sure to only use pure virtual methods in the interface classes.
class IDrawable {
public:
virtual ~IDrawable();
virtual void doSomething() = 0;
};
class IExtendedDrawable: virtual public IDrawable {
public:
virtual ~IExtendedDrawable();
virtual void doSomethingElse() = 0;
};
class DrawableImplementation: virtual public IDrawable {
public:
virtual ~DrawableImplementation();
virtual void doSomething() {/*code here*/}
};
class ExtendedDrawableImplementation:
public DrawableImplementation, public IExtendedDrawable
{
public:
virtual ~ExtendedDrawableImplementation();
virtual void doSomething() {/*code here*/}
virtual void doSomethingElse() {/*code here*/}
};
It largely depends on the logic inside the classes is, but IMO you're better off using composition instead:
class ExtendedDrawableImplementation : public IExtendedDrawable
{
IDrawable* drawableImplementation; //points to a DrawableImplementation
public:
virtual ~ExtendedDrawableImplementation();
};
Multiple inheritance is rarely the answer.
Just derive ExtendedDrawableImplementation from IExtendedDrawable. That way it will have both interfaces anyway. I don't see why you would want to derive from both here.
I'm not C++ programmer, but from what I remember, it's correct. You don't have IDrawable twice, but you have multiple path to it. See http://en.wikipedia.org/wiki/Diamond_problem#The_diamond_problem
Related
I'm asked to implement an interface and I'm wondering what would be the best strategy to factorize the code as much as possible.
Here is the interface definition (I'm not supposed to change it):
#include <string>
class BaseIf
{
public:
virtual ~BaseIf() {}
virtual std::string getName() = 0;
};
class IntIf : public BaseIf
{
public:
virtual ~IntIf() {}
virtual int getValue() = 0;
};
class FloatIf : public BaseIf
{
public:
virtual ~FloatIf() {}
virtual float getValue() = 0;
};
I'll end up with IntImpl (implementing IntIf) and FloatImpl (implementing FloatIf). But I'm wondering where I should put any code common to those two classes (like the name attribute management or any other stuff required by BaseIf which is actually much bigger than in this MCVE).
If I create BaseImpl (implementing BaseIf's getName function) with the common code, and have IntImpl derive from it (and IntIf), then I need to also implement getName in it because it's reported as not implemented. And I also get double inheritance of BaseIf...
I was wondering if Pimpl pattern would help, then IntImpl would have a BaseImpl object as attribute (and only derive from IntIf), but then, again, I need to implement getName in IntImpl to "forward" the call to the BaseImpl attribute. So as BaseIf has actually many virtual functions this is just going to be a real pain to maintain.
Is there no smart solution/pattern making it possible to implement once only getName in a common place? Or is it just the interface that is bad and should be reworked?
This is the primary use case for virtual inheritance.
Despite all the stigma that surrionds multiple and virtual inheritance, there are no particular problems when oure interfaces (no data members) are virtually inherited. Here's the gist:
class BaseIf
{
public:
virtual ~BaseIf() {}
virtual std::string getName() = 0;
};
class IntIf : public virtual BaseIf
{
public:
virtual ~IntIf() {}
virtual int getValue() = 0;
};
class BaseImpl : public virtual BaseIf
{
public:
std::string getName () override { return "whoa dude"; }
};
class IntImpl : public virtual IntIf, public BaseImpl
{
public:
int getValue() override { return 42; }
};
full demo
With a deeper hierarchy one probably would have to virtually inherit implementation classes as well, which is not very convenient but still doable.
An alternative to virtual inheritance of implementation would be to stratify the implementation into a "building blocks" layer and the final layer. Building blocks are standalone and do not inherit other building blocks. (They may inherit interfaces). The final classes inherit building blocks but not other final classes.
class BaseBlock : public virtual BaseIf
{
public:
std::string getName () override { return "whoa dude"; }
};
class IntBlock : public virtual IntIf
{
public:
int getValue() override { return 42; }
};
class BaseImpl : public BaseBlock {};
class IntImpl : public BaseBlock, public IntBlock {};
full demo
One does need to made changes to the interfaces if there was no virtual inheritance in the hierarchy. These changes are however transparent (the clients code need not be changed, only recompiled) and probably beneficial anyway.
Without virtual inheritance, one would have to resort to lots of boilerplate.
class BaseBlock // no base class!
{
public:
virtual std::string getName () { return "whoa dude"; }
};
class BaseImpl : public BaseIf, public BaseBlock
{
public:
// oops, getName would be ambiguous here, need boplerplate
std::string getName () override { return BaseBlock::getName(); }
};
You can make a template class that implements the common part of an interface like this:
template <class IFACE> class BaseImpl : public IFACE
{
public:
std::string getName () override { ... }
}
and then
class IntImpl : public BaseImpl<IntIf>
{
public:
int getValue() override { ... }
}
The result is a simple single-inheritance chain. BaseIf <- IntIf <- BaseImpl <- IntImpl
Make sure you have a good reason for IntIf and FloatIf to exist, though -- in your MCVE they look like they don't need to be there at all.
You can provide default implementation for pure virtual functions:
struct A {
virtual void frob() = 0;
};
void A::frob() {
std::cout << "default";
}
struct B : A {
void frob() override {
A::frob(); // calls the default
}
};
If I'm reading your problem correctly, you'd like a default implementation for getName(). So solve that, simply provide an implementation and call it:
class IntIf : public BaseIf
{
public:
virtual ~IntIf() {}
virtual int getValue() = 0;
std::string getName() override {
return BaseIf::getName();
}
};
class FloatIf : public BaseIf
{
public:
virtual ~FloatIf() {}
virtual float getValue() = 0;
std::string getName() override {
return BaseIf::getName();
}
};
I need help for an implementation that uses multiple inheritance of Interfaces...
There is an existing code whith an interface which has a lot of functions. The instances are created using a factory.
class IBig
{
// Lot of pure virtual functions
};
And his inplementation:
class CBig: public IBig
{
// Implementation
}
I Want to split the interface in multiple smaller interfaces, but it should stay compatible to the existing code for some time.
Here is a sample of what I tried to do:
class IBaseA
{
public:
virtual void DoA() = 0;
};
class IBaseB
{
public:
virtual void DoB() = 0;
};
// The same interface, now based on multiple smaller interfaces
class IBig : public IBaseA, public IBaseB
{
};
class CBaseA: public IBaseA
{
public:
virtual void DoA()
{
printf("DoA\n");
}
};
class CBaseB: public IBaseB
{
public:
virtual void DoB()
{
printf("DoB\n");
}
};
// Inherit from base classes where the implementation is, and from IBig as
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};
The problem here is that the class CBig cannot be instanciated. The compiler says the functions DoA and DoB are pure virtual, even if they are inplemented in CBaseA and CBaseB. What should I do if i don't want to implement again the functions, just to call the function of the base class ?
NB: I know the design is ugly, but this is only temporary until the big interface can be replaced, and.... I want to understand ! ;-)
Thanks in advance !
Here we should use virtual inheritance. This feature assures that there is only one instance of your virtually-inherited base class when you instantiate a subclass. For your example, this would look like:
#include <cstdio>
class IBaseA
{
public:
virtual void DoA() = 0;
};
class IBaseB
{
public:
virtual void DoB() = 0;
};
// The same interface, now based on multiple smaller interfaces
class IBig : virtual public IBaseA, virtual public IBaseB
// ^ ^
{
};
class CBaseA: virtual public IBaseA
// ^
{
public:
virtual void DoA()
{
printf("DoA\n");
}
};
class CBaseB: virtual public IBaseB
// ^
{
public:
virtual void DoB()
{
printf("DoB\n");
}
};
// Inherit from base classes where the implementation is, and from IBig as
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};
int main()
{
CBig cb;
}
The above changes ensure that there are not extra declarations of DoA and DoB created when you inherit from IBaseA and IBaseB multiple times.
This is a classic example of virtual inheritance in C++ (copied from cprogramming.com):
class storable
{
public:
storable(const char*);
virtual void read();
virtual void write();
virtual ~storable();
private:
// some data...
};
class transmitter : public virtual storable
{
public:
void write();
...
};
class receiver : public virtual storable
{
public:
void read();
...
};
class radio : public transmitter, public receiver
{
public:
...
};
I have used this kind of approach before on similar hierarchies, however, I was interested in finding out what other alternatives do we have for this specific example. How could we replace virtual inheritance in this case? Using some form of composition? Mixins?
Or is virtual inheritance indeed the best approach?
There was an interesting presentation in the last Going Native conference that I think would apply here.
Inheritance Is The Base Class of Evil by Sean Parent.
Please refer the following example.
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1();
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
In the above example, for all other entities deriving from IBase needs to implement BaseMethod1() and BaseMethod2().Because of which lots of code duplication is happening? Is there anyway where we can avoid redundant implementation of IBase methods in entities deriving from it?
You can use virtual inheritance in combination with a default base implementation class to encapsulate your default base behavior, and have it be only inherited by the concrete classes you want, like follows:
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : virtual public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class BaseImpl : virtual public IBase
{
public:
virtual void BaseMethod1()
{
...
}
virtual void BaseMethod2()
{
...
}
}
class Entity1 : public IEntity1, public BaseImpl
{
public:
Entity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
There is, however, a runtime cost associated with virtual inheritance. Multiple inheritance also comes with some structural issues, e.g. base class construction.
You can even have some fun with template classes to make your class composition more modular:
template<typename TEntity, typename TBaseImpl>
class ConcreteEntity: public TEntity, public TBaseImpl
{
public:
ConcreteEntity() {}
};
class ConreteEntity1 : public ConcreteEntity<IEntity1, BaseImpl>
{
public:
ConreteEntity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//ConreteEntity1 Methods
void Method1();
void Method2();
};
You could make a function that is called in BaseMethod1() implementations that are the same.
Something like this:
void BaseMethod1_common();
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1() { BaseMethod1_common(); }
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
First of all IBase deserves a virtual destructor.
Declare it pure virtual and define IBase:BaseMethod1() and
IBase::BaseMethod1().
If your intention is to hide implementation, then the only option would be to release the code as a library and then share only the header file among the other developers.
Implementing a global function, or using multiple inheritance as suggested still mean that your implementation is exposed.
However, if the intent is to reduce coupling among the various classes, there's another option :
Create a class that has the actual shared implementation, and then another class which will be an interface to it.
This interface class will then be the base class for other derived entities.
Example code is shown below :
//First Header and Cpp file
class Base_private
{
public:
BaseImpl(arguments);
~BaseImpl();
void BaseMethod1() {
//Implementation
}
void BaseMethod2() {
//Implementation
}
};
//Second Header and Cpp file
class BaseInterface
{
public:
BaseInterface(arguments);
~BaseInterface();
void BaseMethod1() {
m_pBase->BaseMethod1();
}
void BaseMethod2() {
m_pBase->BaseMethod2();
}
private:
Base_private* m_pBase;
};
class Entity : public BaseInterface
{
public:
Entity(arguments);
~Entity();
void Method1();
void Method2();
};
I have been working on a Roguelike, and run into a problem with it. My problem is that I would like to use "polymorphic overloading" or sorts, but I'm guessing C++ doesn't support.
My class diagram is like this:
xMapObject <- xEntity <- xVehicle
An the problem is, it is possible to have this:
class xMapObject
{
public:
virtual void Bump(xMapObject *MapObject);
virtual void Bump(xEntity *Entity);
virtual void Bump(xVehicle *Vehicle);
virtual void BumpedBy(xMapObject *MapObject);
virtual void BumpedBy(xEntity *Entity);
virtual void BumpedBy(xVehicle *Vehicle);
};
This would be a very nice, as it would great simplify the code that determines who bumps into what, but since this doesn't work, is there another object oriented approach similar to this? Or is the best option casting objects to determine what they are?
Thanks for any help!
Sure it works. I think though that you expect it to be able to tell the difference when you pass it an xMapObject* and that simply won't happen.
You need a double dispatch mechanism. Perhaps visitor but I'm doubting it. See Modern C++ Design or wiki for multimethods.
It's possible, but this design seems awkward to me.
namespace {
class xEntity;
class xVehicle;
class xMapObject {
public:
virtual void Bump(xMapObject *MapObject);
virtual void Bump(xEntity *Entity);
virtual void Bump(xVehicle *Vehicle);
virtual void BumpedBy(xMapObject *MapObject);
virtual void BumpedBy(xEntity *Entity);
virtual void BumpedBy(xVehicle *Vehicle);
};
class xEntity : public xMapObject {};
class xVehicle : public xMapObject {};
}
I think I would do something like this instead:
namespace {
class xMapObject {
public:
virtual void Bump(xMapObject *MapObject);
virtual void BumpedBy(xMapObject *MapObject);
};
class xEntity : public xMapObject {
public:
void Bump(xMapObject *MapObject);
void BumpedBy(xMapObject *MapObject);
};
class xVehicle : public xMapObject {
public:
void Bump(xMapObject *MapObject);
void BumpedBy(xMapObject *MapObject);
};
}