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);
};
}
Related
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 a base class and n derived class. I want to instantiate a derived class and send it to a function that receive as an argument a base class. Inside the function, I found which type of derived class it is by using dynamic_cast, but I don't want to use several if-else sentences. Instead, I would like to know if there is a way to find out which derived class is it in order to cast it.
Here I leave my code as an example.
class animal{
public:
virtual ~animal() {}
int eyes;
};
class dog: public animal{
public:
int legs;
int tail;
};
class fish: public animal{
public:
int mostage;
};
void functionTest(animal* a){
if(dynamic_cast<fish*>(a) != NULL){
do_something();
}
else if(dynamic_cast<dog*>(a) != NULL){
do_something();
}
};
I would like to have a more general approach to this. Something like dynamic_cast(a). Thank you!
It's great to do this for quick drafts if you need to demonstrate something in a few minutes, but usually you try to avoid using dynamic_cast this way - it can lead to extremely high maintenance costs if used in the wrong places. Various patterns are available, such as a simple method overload, the Visitor pattern, or a virtual "GetType" function (which could be implemented with the curiously recurring template pattern, if you like patterns).
I'll list all 3 approaches. The first one is by far the most straightforward, and easiest to use. The advantages of the other 2 is that each of them moves the decision of what to do to a different part of the code, which can be a huge benefit (or drawback).
Lets assume this is what you want to do:
void functionTest(animal* a)
{
if(dynamic_cast<fish*>(a) != NULL)
blub();
else if(dynamic_cast<dog*>(a) != NULL)
bark();
};
Simple virtual function approach:
class animal {
public:
virtual ~animal() {}
virtual void do_something() = 0;
int eyes;
};
class dog : public animal {
public:
virtual void do_something() { bark(); } // use override in C++11
int legs;
int tail;
};
class fish: public animal {
public:
virtual void do_something() { blub(); } // use override in C++11
int mostage;
};
void functionTest(animal* a)
{
if (a) a->do_something();
};
Visitor approach:
class IVisitor {
public:
~IVisitor(){}
virtual void visit(const fish&){}
virtual void visit(const dog&){}
virtual void visit(const animal&){}
};
class animal {
public:
virtual ~animal() {}
virtual void accept(IVisitor& visitor) = 0;
int eyes;
};
class dog : public animal {
public:
virtual void accept(IVisitor& visitor) { visitor.visit(*this); } // use override in C++11
int legs;
int tail;
};
class fish : public animal {
public:
virtual void accept(IVisitor& visitor) { visitor.visit(*this); } // use override in C++11
int mostage;
};
class MyVisitor : public IVisitor {
public:
virtual void visit(const fish&) { blub(); } // use override in C++11
virtual void visit(const dog&) { bark(); } // use override in C++11
};
void functionTest(animal* a)
{
if (a)
{
MyVisitor v;
a->accept(v);
}
};
GetType approach, with CRTP spice:
class animal {
public:
virtual ~animal() {}
virtual const type_info& getType() const = 0; // careful. typeinfo is tricky of shared libs or dlls are involved
int eyes;
};
template <class T>
class BaseAnimal : public animal {
// these are C++11 features. Alternatives exist to ensure T derives from BaseAnimal.
static_assert(std::is_base_of<BaseAnimal,T>(,"Class not deriving from BaseAnimal");// C++11
virtual const type_info& getType() const { return typeid(T); }
};
class dog : public BaseAnimal<dog> {
public:
int legs;
int tail;
};
class fish : public BaseAnimal<fish> {
public:
int mostage;
};
void functionTest(animal* a)
{
if (!a)
return;
if (a->getType() == typeid(fish))
blub();
else if (a->getType() == typeid(dog))
bark();
};
Notice that you should consider the above examples to be pseudo-code. For best practices you will need to look up the patterns. Also, the curiously recurring template pattern can also be used in the second approach, or it can be easily removed from the third. It's just for convenience in these cases.
You may use virtual functions for that:
class animal{
public:
virtual ~animal() {}
virtual void do_thing() = 0;
};
class dog: public animal{
public:
void do_thing() override { std::cout << "I'm a dog" << std::endl; }
};
class fish: public animal{
public:
void do_thing() override { std::cout << "I'm a fish" << std::endl; }
};
And then
void functionTest(animal& a){
a.do_thing();
}
As an alternative, if you want to avoid to have to many virtual functions, you may use visitor pattern
Let me strongly urge you to NOT do what you have here and to follow the very wise advice that everyone has given to use polymorphism (e.g. virtual functions). The approach you've outlined could be made to work, but it is working against the tools the language provides. What you are trying to do is exactly why the language has virtual functions.
With your method, if you add a new sub-class of animal then you also have to change function_test(), and function_test() is doing what the compiler would do for virtual functions anyway, but in a much clumsier and inefficient way.
Using virtual functions, all you have to do is implement do_something() in the new sub-class and the compiler takes care of the rest.
Don't use dynamic_cast<>() for this. That's not what it is for.
Consider implementing this "switch" as virtual functions.
If you do not want that, you can either use dynamic_cast as in your example, or you use the typeid operator to compute a mapping for the result of typeid to a function that implements the do_something code.
However, I would not recommend that, as you just end up with a hand-coded vtable. It is better to use virtual functions and let the compiler generate the mapping.
For additional reading, I recommend Herb Sutter's article Type inference vs static/dynamic typing. He mentions Boost variant and Boost any, which might be possible alternatives for your problem.
The "classical" type-switch by Stroustrup may be suitable for your needs:
https://parasol.tamu.edu/mach7/
https://parasol.tamu.edu/~yuriys/pm/
Basically it will let you do a switch-case like based on obect type, using one of three different implementations
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 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