How to "skip" certain child class functions - c++

I wasn't sure how to exactly title this, but I am trying to figure out something with polymorphism.
So basically, I want to have an array of the parent class (object) that holds a bunch of it's child classes (ones that are and aren't collidable). However, I want to be able to put this array into a loop and run the collision function for only the collidable child class, but since the other child class doesn't have a collide function, how can I do this?
(Looks something like this)
class Object
{
protected:
Image image; // Pseudo code to make point
public:
void Collision() = 0;
//Constructor/Destructor
Object(void);
~Object(void);
};
class Collidable : Object
{
private:
Position myPosition; // Pseudo code to make point
public:
void Collision(); // Has collision function for parent class
//Constructor/Destructor
Collidable(void);
~Collidable(void);
};
class Uncollidable : Object
{
private:
Position myPosition; // Pseudo code to make point
public:
// No collision function for parent class
//Constructor/Destructor
Uncollidable(void);
~Uncollidable(void);
};
int main()
{
Collidable collide1, collide2, collide3;
Uncollidable uncollide1, uncollide2, uncollide3;
Object *objects[] { collide1, collide2, uncollide1, uncollide2, uncollide3, collide3 };
for(int i = 0; i < 6; i++)
{
objects[i].Collide(); // Should not work.
}
return 0;
}
^(this was just an example to help show my question, do pardon some of the syntax errors if any)
I'm pretty sure, however, that something like this would be an error since void Collide() doesn't exist in the Uncollidable class. So how might I be able to still run the void Collide() function in the loop while avoiding error? Or is something like this impossible and I just have to make two separate arrays?
I hope I explained my question well.
(I tried to research this, but every time I tried I just got sent to the basics of polymorphism)

You can just do this:
for(int i = 0; i < 6; i++)
{
Collidable c = dynamic_cast<Collidable*>(objects[i]);
if(c != nullptr) // dynamic_cast will return null if objects[i] is not of type Collidable
c->Collide(); // Should work.
}
In your code there is one bug, you have made Collide() pure virtual in class Object, but you are not overriding it in Uncollidable. It will not work. Either override it in Uncollidable (which is inappropriate), or give a default body to Object::Collide() (which is inappropriate also).
There is a better design, put all the common interface in Object, separate out different behaviors in other interface. It will lead to good OO design ( compliant with IS-A relationship)
class Object
{
protected:
Image image; // Pseudo code to make point
public:
Object(void);
~Object(void);
//other common interface
};
class Collidable // this is an interface that represent 'collidable' behavior
{
public:
virtual void Collision() = 0;
}
class CollidableObject : public Object, public Collidable
{ ... }
class UncollidableObject : public Object
{ ... }
Note: Object must be inherited publicly, otherwise you will not be able to treat object os CollidableObject and UncollidableObject as object of Object.

Related

Using the strategy pattern if the concrete strategy depends on the concrete parameter type

I'm currently working with a System/Data hierarchy implemented like this:
class SystemData
{
}
class SystemDataA : public SystemData
{
int x;
}
class SystemDataB : public SystemData
{
float y;
}
class System
{
virtual SystemData* getData() = 0;
virtual Result computeData(SystemData*) = 0;
}
class SystemA : public System
{
// really returns SystemDataA
SystemData* getData() override;
Result computeData(SystemData*) override;
}
class SystemB : public System
{
// really returns SystemDataB
SystemData* getData() override;
Result computeData(SystemData*) override;
}
In the end there is a controller class which does sth similar to this:
void foo()
{
for(auto& s : systemVec)
{
SystemData* data = s->getData();
FinalResult final = s->computeData(data);
}
}
Whereas now each specific system dynamic_casts back to the concrete type it is able to process. This seems like pretty bad design and I'd like to refactor this into sth more reasonable. My first idea was to just implement the computation algorithm inside the SystemData classes and then just do:
SystemData* data = s->getData();
FinalResult final = data->compute();
but does it really belong there?
It appears more intuitive to have a separate algorithm hierarchy, probably implemented with the strategy pattern. However then I again have the problem of losing runtime type info of the data because all algorithms get passed the abstract data type and in the end will have to dynamic cast and do nullptr and error checks again. So is it still better to implement the algorithm inside the data classes itself? Can I maybe still implement the hierarchy in a separate module and just add function pointers or a similar construct to the data class? Is there a completely different solution I'm not aware of?

Best way to store all entities in C++ game

I'm trying to create a way to hold all entities in my C++ game, arrays wouldn't work since they are limited to one type. I need to store anything with the class Entity, and all it's derivatives in it. I've been trying all day to get a way to store all game entities in a way I can just loop through them all and draw them. Still haven't found a solution.
Assuming Entity is some base class that many things derive from, you can have a container (any container is fine, but std::vector is a good place to start unless you have some other specific requirements).
class Entity
{
public:
virtual void Draw() = 0;
};
class Atom : public Entity
{
public:
void Draw() override {}
};
class Environment : public Entity
{
public:
void Draw() override {}
};
int main()
{
std::vector< std::shared_ptr<Entity> > entities;
entities.push_back(std::make_shared<Atom>());
entities.push_back(std::make_shared<Environment>());
// Draw entities:
for (size_t ent = 0; ent < entities.size(); ++ent)
{
entities[ent]->Draw();
}
return 0;
}
You might be able to use std::vector. It has a lot of built-in functions for simple data manipulation, and you can use it with any type.

Converting objects of base class to derived class

I asked a couple days ago some clarifications on inheritance, a concept I am still trying to understand. Here is the follow up question, since I am still facing problems.
In my project I have 2 types of objects, Hand and Face, both inheriting from the base class BodyPart. BodyPart is something like this:
class BodyPart
{
public:
typedef boost::shared_ptr<BodyPart> BodyPartPtr;
BodyPart();
virtual ~BodyPart();
private:
int commonMember1;
double commonMember2;
public:
int commonMethod1();
int CommonMethod2();
}
while Hand is something like this:
class Hand : public BodyPart
{
public:
Hand();
~Hand();
private:
int numFingers;
double otherVar;
public:
int getNumFingers();
void printInfo();
}
I also have a vector of BodyPart elements
std::vector<BodyPart::BodyPartPtr> cBodyParts;
composed of Hand or Head objects. In the previous question I was told that this approach makes sense, I just had to cast from the base class to the derived using boost static_pointer_cast
Now, the problem now is that for some of the objects in the vector I don't know whether they are Hand or Head, so at some point in my code I can have in cBodyParts some Hand elements, some Head elements as well as some BodyPart elements. After some further analysis I am able to correctly classify the latter as either Hand or Head and modify accordingly the elements in the vector, but I have no idea on how to make it. Shall I just delete the case class element and create a derived one with the same property? Shall I just avoid inheritance in case like this?
Thanks in advance for the help
EDIT: I have augmented the examples to make them clearer.
Relaying on casts is usually a sign of a bad design. Casts have their place, but this does not look to be it.
You need to ask yourself what do you want to do with the objects stored in cBodyParts. For sure, you will be doing different things with a Hand or with a Head, but you can probably abstract them somehow: this is what virtual functions do. So, in addition to what you have already written for your classes, you would just need an additional virtual function in them:
class BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() = 0; // Pure virtual: each body part must say how to process itself
virtual void CalibrateJoints() {} // Override it only if the body part includes joints
}
class Head : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Head
}
// Since a Head has no joints, we don't override the CalibrateJoints() method
}
class Hand : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Hand
}
virtual void CalibrateJoints() {
// Code to calibrate the knuckles in the hand
}
}
And then you no longer need any casts. For instance:
for (BodyPart::BodyPartPtr part : cBodyParts) {
part->InitialisePart();
part->CalibrateJoints(); // This will do nothing for Heads
}
As you can see, no casts at all and everything will work fine. This scheme is extensible; if you later decide that you need additional classes inheriting from BodyPart, just write them and your old code will work correctly:
class Torso : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Torso
}
// The Torso has no joints, so no override here for CalibrateJoints()
// Add everything else the class needs
}
class Leg : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Leg
}
virtual void CalibrateJoints() {
// Code to calibrate the knee
}
// Add everything else the class needs
}
Now you don't need to change the code you wrote previously: the for loop above will work correctly with and Torso or Leg it finds with no need for an update.
The hip bone's connected to the thigh bone...
I take it you have some composite of all the body parts, maybe a Body class.
What do you want the body to do?
Render itself
Serialise
Ouput its volume, or bounding box, or some other metric
Re-orient itself in response to input
Respond to an inverse-kinematic physical model
The list could probably go on. If you know exactly what you want the Body to do you can put that function in the BodyPart base class, and have Body iterate over the composite hierarchical structure of all the connected body parts, calling render, for example.
An alternative is to use a Visitor, which is effectively a way of dynamically adding methods to a static inheritance hierarchy.
As Kerrek SB pointed out this is not feasible at all, but for the sake of answering the actual question, dynamic_cast is what you are looking for.
Use virtual functions, they will simplify a lot your problem.
Else, you can add some methods to distinguish between different types. However, do it only if you cannot do it another way, ie if you cannot do it via virtual functions.
Example 1:
// in BodyPart; to be reimplemented in derived classes
virtual bool isHand() const { return false; }
virtual bool isHead() const { return false; }
// in Hand (similar to what will be in Head)
bool isHand() const { return true; }
// How to use:
BodyPart::pointer ptr = humanBodyVector[42]; // one item from the array
if(ptr->isHand())
processHand(/*cast to hand*/)
else if(ptr->isHead())
// ...
Example 2: let the derived classes handle the cast
// in BodyPart; to be reimplemented in derived classes
virtual Hand* toHand() const { return 0; }
virtual Head* toHead() const { return 0; }
// in Hand (similar to what will be in Head)
Hand* toHand() const { return this; }

calling a function from a set of overloads depending on the dynamic type of an object

I feel like the answer to this question is really simple, but I really am having trouble finding it. So here goes:
Suppose you have the following classes:
class Base;
class Child : public Base;
class Displayer
{
public:
Displayer(Base* element);
Displayer(Child* element);
}
Additionally, I have a Base* object which might point to either an instance of the class Base or an instance of the class Child.
Now I want to create a Displayer based on the element pointed to by object, however, I want to pick the right version of the constructor. As I currently have it, this would accomplish just that (I am being a bit fuzzy with my C++ here, but I think this the clearest way)
object->createDisplayer();
virtual void Base::createDisplayer()
{
new Displayer(this);
}
virtual void Child::createDisplayer()
{
new Displayer(this);
}
This works, however, there is a problem with this:
Base and Child are part of the application system, while Displayer is part of the GUI system. I want to build the GUI system independently of the Application system, so that it is easy to replace the GUI. This means that Base and Child should not know about Displayer. However, I do not know how I can achieve this without letting the Application classes know about the GUI.
Am I missing something very obvious or am I trying something that is not possible?
Edit: I missed a part of the problem in my original question. This is all happening quite deep in the GUI code, providing functionality that is unique to this one GUI. This means that I want the Base and Child classes not to know about the call at all - not just hide from them to what the call is
It seems a classic scenario for double dispatch. The only way to avoid the double dispatch is switching over types (if( typeid(*object) == typeid(base) ) ...) which you should avoid.
What you can do is to make the callback mechanism generic, so that the application doesn't have to know of the GUI:
class app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base&) = 0;
virtual void call(derived&) = 0;
};
class Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
class Child : public Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
You could then use this machinery like this:
class display_callback : public app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base& obj) { displayer = new Displayer(obj); }
virtual void call(derived& obj) { displayer = new Displayer(obj); }
Displayer* displayer;
};
Displayer* create_displayer(Base& obj)
{
display_callback dcb;
obj.call_me_back(dcb);
return dcb.displayer;
}
You will have to have one app_callback::call() function for each class in the hierarchy and you will have to add one to each callback every time you add a class to the hierarchy.
Since in your case calling with just a base& is possible, too, the compiler won't throw an error when you forget to overload one of these functions in a callback class. It will simply call the one taking a base&. That's bad.
If you want, you could move the identical code of call_me_back() for each class into a privately inherited class template using the CRTP. But if you just have half a dozen classes it doesn't really add all that much clarity and it requires readers to understand the CRTP.
Have the application set a factory interface on the system code. Here's a hacked up way to do this. Obviously, apply this changes to your own preferences and coding standards. In some places, I'm inlining the functions in the class declaration - only for brevity.
// PLATFORM CODE
// platformcode.h - BEGIN
class IDisplayer;
class IDisplayFactory
{
virtual IDisplayer* CreateDisplayer(Base* pBase) = 0;
virtual IDisplayer* CreateDisplayer(Child* pBase) = 0;
};
namespace SystemDisplayerFactory
{
static IDisplayFactory* s_pFactory;
SetFactory(IDisplayFactory* pFactory)
{
s_pFactory = pFactory;
}
IDisplayFactory* GetFactory()
{
return s_pFactory;
}
};
// platformcode.h - end
// Base.cpp and Child.cpp implement the "CreateDisplayer" methods as follows
void Base::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
void Child::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
// In your application code, do this:
#include "platformcode.h"
class CDiplayerFactory : public IDisplayerFactory
{
IDisplayer* CreateDisplayer(Base* pBase)
{
return new Displayer(pBase);
}
IDisplayer* CreateDisplayer(Child* pChild)
{
return new Displayer(pChild);
}
}
Then somewhere early in app initialization (main or WinMain), say the following:
CDisplayerFactory* pFactory = new CDisplayerFactory();
SystemDisplayFactory::SetFactory(pFactory);
This will keep your platform code from having to know the messy details of what a "displayer" is, and you can implement mock versions of IDisplayer later to test Base and Child independently of the rendering system.
Also, IDisplayer (methods not shown) becomes an interface declaration exposed by the platform code. Your implementation of "Displayer" is a class (in your app code) that inherits from IDisplayer.

Adding virtual functions without modifying the original classes

Let's say we already have a hierarchy of classes, e.g.
class Shape { virtual void get_area() = 0; };
class Square : Shape { ... };
class Circle : Shape { ... };
etc.
Now let's say that I want to (effectively) add a virtual draw() = 0 method to Shape with appropriate definitions in each sub-class. However, let's say I want to do this without modifying those classes (as they are part of a library that I don't want to change).
What would be the best way to go about this?
Whether or not I actually "add" a virtual method or not is not important, I just want polymorphic behaviour given an array of pointers.
My first thought would be to do this:
class IDrawable { virtual void draw() = 0; };
class DrawableSquare : Square, IDrawable { void draw() { ... } };
class DrawableCircle : Circle, IDrawable { void draw() { ... } };
and then just replace all creations of Squares and Circles with DrawableSquares and DrawableCircles, respectively.
Is that the best way to accomplish this, or is there something better (preferably something that leaves the creation of Squares and Circles intact).
Thanks in advance.
(I do propose a solution down further... bear with me...)
One way to (almost) solve your problem is to use a Visitor design pattern. Something like this:
class DrawVisitor
{
public:
void draw(const Shape &shape); // dispatches to correct private method
private:
void visitSquare(const Square &square);
void visitCircle(const Circle &circle);
};
Then instead of this:
Shape &shape = getShape(); // returns some Shape subclass
shape.draw(); // virtual method
You would do:
DrawVisitor dv;
Shape &shape = getShape();
dv.draw(shape);
Normally in a Visitor pattern you would implement the draw method like this:
DrawVisitor::draw(const Shape &shape)
{
shape.accept(*this);
}
But that only works if the Shape hierarchy was designed to be visited: each subclass implements the virtual method accept by calling the appropriate visitXxxx method on the Visitor. Most likely it was not designed for that.
Without being able to modify the class hierarchy to add a virtual accept method to Shape (and all subclasses), you need some other way to dispatch to the correct draw method. One naieve approach is this:
DrawVisitor::draw(const Shape &shape)
{
if (const Square *pSquare = dynamic_cast<const Square *>(&shape))
{
visitSquare(*pSquare);
}
else if (const Circle *pCircle = dynamic_cast<const Circle *>(&shape))
{
visitCircle(*pCircle);
}
// etc.
}
That will work, but there is a performance hit to using dynamic_cast that way. If you can afford that hit, it is a straightforward approach that is easy to understand, debug, maintain, etc.
Suppose there was an enumeration of all shape types:
enum ShapeId { SQUARE, CIRCLE, ... };
and there was a virtual method ShapeId Shape::getId() const = 0; that each subclass would override to return its ShapeId. Then you could do your dispatch using a massive switch statement instead of the if-elsif-elsif of dynamic_casts. Or perhaps instead of a switch use a hashtable. The best case scenario is to put this mapping function in one place, so that you can define multiple visitors without having to repeat the mapping logic each time.
So you probably don't have a getid() method either. Too bad. What's another way to get an ID that is unique for each type of object? RTTI. This is not necessarily elegant or foolproof, but you can create a hashtable of type_info pointers. You can build this hashtable in some initialization code or build it dynamically (or both).
DrawVisitor::init() // static method or ctor
{
typeMap_[&typeid(Square)] = &visitSquare;
typeMap_[&typeid(Circle)] = &visitCircle;
// etc.
}
DrawVisitor::draw(const Shape &shape)
{
type_info *ti = typeid(shape);
typedef void (DrawVisitor::*VisitFun)(const Shape &shape);
VisitFun visit = 0; // or default draw method?
TypeMap::iterator iter = typeMap_.find(ti);
if (iter != typeMap_.end())
{
visit = iter->second;
}
else if (const Square *pSquare = dynamic_cast<const Square *>(&shape))
{
visit = typeMap_[ti] = &visitSquare;
}
else if (const Circle *pCircle = dynamic_cast<const Circle *>(&shape))
{
visit = typeMap_[ti] = &visitCircle;
}
// etc.
if (visit)
{
// will have to do static_cast<> inside the function
((*this).*(visit))(shape);
}
}
Might be some bugs/syntax errors in there, I haven't tried compiling this example. I have done something like this before -- the technique works. I'm not sure if you might run into problems with shared libraries though.
One last thing I'll add: regardless of how you decide to do the dispatch, it probably makes sense to make a visitor base class:
class ShapeVisitor
{
public:
void visit(const Shape &shape); // not virtual
private:
virtual void visitSquare(const Square &square) = 0;
virtual void visitCircle(const Circle &circle) = 0;
};
What you're describing is somewhat like the decorator pattern. Which is very suitable to change runtime behaviour of existing classes.
But I don't really see how to implement your practical example, if shapes have no way to be drawn, then there's no way to change drawing behaviour at runtime either...
But I suppose this is just a very simplified example for stackoverflow? If all the basic building blocks for the desired functionality are available, then implementing the exact runtime behaviour with such a pattern is certainly a decent option.
One 'off the wall' solution you might like to consider, depending on the circumstance, is to use templates to give you compile time polymorphic behaviour. Before you say anything, I know that this will not give you traditional runtime polymorphism so it may well not be useful but depending on the limitations of the environment in which you're working, it can prove useful:
#include <iostream>
using namespace std;
// This bit's a bit like your library.
struct Square{};
struct Circle{};
struct AShape{};
// and this is your extra stuff.
template < class T >
class Drawable { public: void draw() const { cout << "General Shape" << endl; } };
template <> void Drawable< Square >::draw() const { cout << "Square!" << endl; };
template <> void Drawable< Circle >::draw() const { cout << "Circle!" << endl; };
template < class T >
void drawIt( const T& obj )
{
obj.draw();
}
int main( int argc, char* argv[] )
{
Drawable<Square> a;
Drawable<Circle> b;
Drawable<AShape> c;
a.draw(); // prints "Square!"
b.draw(); // prints "Circle!"
c.draw(); // prints "General Shape" as there's no specific specialisation for an Drawable< AShape >
drawIt(a); // prints "Square!"
drawIt(b); // prints "Circle!"
drawIt(c); // prints "General Shape" as there's no specific specialisation for an Drawable< AShape >
}
The drawIt() method is probably the key thing here as it represents generic behaviour for any class meeting the requirement of having a draw() method. Do watch out for code bloat here though as the compiler will instantiate a separate method for each type passed.
This can be useful in situations where you need to write one function to work on many types which have no common base class. I'm aware that this is not the question you asked, but I thought I'd throw it just as an alternative.