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.
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 came from JVM world and I try to implement something in c++.
I have an interface:
class MyInterface
{
public:
virtual void my_method(std::string i) = 0;
virtual void my_method(int i) = 0;
};
And I would like to have two subclasses A and B:
class AClass: public MyInterface
{
public:
void my_method(std::string i); // And implement only that method in .c file
}
And class B:
public BClass: public MyInterface
{
public:
void my_method(int i); // And implement only that method in .c file
}
But I got errors. (I cannot paste logs because I have production code only and the code above is only the scaffolding of the real problem).
Is there any pattern to avoid overriding some virtual methods?
Is there any pattern to avoid overriding some virtual methods?
I don't think there is any pattern for that. You just have to make sure that all virtual member functions are implemented in the most derived class or one of its parent classes.
A trivial implementation is not too hard for the functions you have.
class AClass: public MyInterface
{
public:
void my_method(std::string i); // And implement only that method in .c file
void my_method(int i) {} // That's all you need
};
Your child classes selectively override parent methods.
You need something like this :
class MyInterface // Consider a different name
{
public:
virtual void my_method(std::string i) {
// Business Logic . Let child 1 override this
}
virtual void my_method(int i) {
// Business Logic . Let child 2 override this
}
};
In short you can't have an abstract base here.
I am looking at refactoring a lot of code and have discussed a bit in relations to the best way of handling inheritance. Given the following three classes
class Listener_Interface {
public:
virtual void message(data& data);
}
class Timing_Interface {
public:
virtual void timerEvent(data& data);
}
class Action_Interface {
public:
virtual void action(data& data);
}
There is a need for a class to implement all these plus provide a some extra specifik methods.
Should I inherit like this:
class NewClass_Interface :
public Listener_Interface,
public Timing_Interface,
public Action_Interface {
public:
virtual void newMethod();
}
class NewClass : NewClass_Interface {
....
}
or
class NewClass_Interface {
public:
virtual void newMethod();
}
class NewClass :
public NewClass_Interface
public Listener_Interface,
public Timing_Interface,
public Action_Interface {
....
}
To me the previous seems more correct and easier to test etc. But for some reason all the classes and code looks lite the latter.
It depends on your logic. Sometimes you might want your NewClass_Interface to not necessarily have a relation with Listener, Timing and Action. But since it doesn't look like the case here, I agree with you. The better you constraint the use of your interfaces, the more reliable your code will be.
So I would go with this:
class Listener_Interface {
public:
virtual void message(data& data) = 0;
}
class Timing_Interface {
public:
virtual void timerEvent(data& data) = 0;
}
class Action_Interface {
public:
virtual void action(data& data) = 0;
}
(Observe how I make your methods pure virtual in order to make your classes real interfaces)
class NewClass_Interface :
public Listener_Interface,
public Timing_Interface,
public Action_Interface
{
public:
virtual void newMethod() = 0;
}
class NewClass : NewClass_Interface {
....
}
This way you'll have better control on what is going on.
Also, I would advise you of using the most common standard for Interfaces naming: IListener, ITiming, IAction and INewClass.
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
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);
};
}