How to use polymorphic method on a container of different classes - c++

I have two classes like below :
class Plot
{
protected:
virtual void plot() = 0;
}
class DynamicPlot : public Plot
{
public:
virtual void update_real_time();
virtual void plot();
}
class StaticPlot : public Plot
{
public:
virtual void plot();
}
And a container like this:
std::vector<Plot*> plot_vector;
plot_vector.append(new DynamicPlot());
plot_vector.append(new DynamicPlot());
plot_vector.append(new StaticPlot());
plot_vector.append(new StaticPlot());
And i want to call update_real_time() if the type of the instance is DynamicPlot.
foreach(Plot *plot, plot_vector)
{
if(/* plot type == DynamicPlot */)
{
plot->update_real_time();
}
plot->plot();
}
Which pattern should i use here ? Adding an empty update_real_time() method into the StaticPlot class doesn't seem like a good solution.
EDIT : The code above is not real. I just wrote it in order to tell my problem, think that as a psuedo code. I didn't bother to write access qualifiers. In my real code, i do not have a private inheritance or slicing issue. I keep pointers of instances in vector. Sorry for misunderstanding. I am fixing it anyway.

You would need to use dynamic_cast:
foreach(Plot *plot, plot_vector)
{
DynamicPlot* p = dynamic_cast<DynamicPlot*>(plot);
if(p)
{
p->update_real_time();
}
plot->plot();
}
Except that foreach is not C++, so you would have to use real code for that too.

Related

Template class and nested class C++

I have a problem with typename SnakeGame. I would like to know how to make SnakeGame to global type in class KeyboardEvents. Now a nested class like DirectionKeyboard don't know what the type SnakeGame is, since it only sees see KeyboardEvents<SnakeGame> type. I don't know how to change it :P
Here's the error:
no know conversion for argument 1 from 'KeyboardEvents SnakeGame>&' to 'SnakeGame&'
I would really appreciate help .
keyboardEvents.hpp
#include<SFML/Graphics.hpp>
template <typename SnakeGame>
class KeyboardEvents {
public:
virtual ~KeyboardEvents() = default;
protected:
class DirectionKeyboardEvent{
public:
virtual ~DirectionKeyboardEvent() = default;
virtual void direction(SnakeGame&) = 0; // error no know conversion
};
class GoRight : public DirectionKeyboardEvent {
public:
void direction(SnakeGame& snakeObj) {
snakeObj.snake[0].xCoor+=1;
}
};
class GoRight : public DirectionKeyboardEvent {
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].xCoor += 1;
}
};
class GoLeft : public DirectionKeyboardEvent{
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].xCoor-=1;
}
};
class GoUp:public DirectionKeyboardEvent{
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].yCoor-=1;
}
};
class GoDown : public DirectionKeyboardEvent{
public:
void direction(SnakeGame& snakeObj){
snakeObj.snake[0].yCoor+=1;
}
};
std::map<sf::Keyboard::Key, std::shared_ptr<DirectionKeyboardEvent>> mapOfDirects;
void initializeDirectionMap() {
mapOfDirects[sf::Keyboard::Right] = std::shared_ptr< DirectionKeyboardEvent >(new GoRight);
mapOfDirects[sf::Keyboard::Left] = std::shared_ptr<DirectionKeyboardEvent>(new GoLeft);
mapOfDirects[sf::Keyboard::Up] = std::shared_ptr<DirectionKeyboardEvent>(new GoUp);
mapOfDirects[sf::Keyboard::Down] = std::shared_ptr<DirectionKeyboardEvent>(new GoDown);
}
void chooseMethodFromKeyboardArrows(sf::Keyboard::Key codeFromKeyboard) {
auto iterator = mapOfDirects.find(codeFromKeyboard);
if(iterator!=mapOfDirects.end()){
iterator->second->direction(*this);//left , right,up , down, pause
mainDirection=codeFromKeyboard;
} else {
mapOfDirects[mainDirection]->direction(*this);
}
}
};
Here's the class where I use KeyboardEvents ~ snakeGame.hpp
#include"keyboardEvents.hpp"
class SnakeGame:public Screen, public KeyboardEvents<SnakeGame> {
public:
SnakeGame(int size=16, int width=15, int height=15, int timeDelay=60000)
: Screen(size, width, height), KeyboardEvents<SnakeGame>(), timeDelay(timeDelay) {}
};
In your try to call the DirectionKeyboardEvent::direction inside the KeyboardEvents class.
Even if you put a template parameter that happens to be the child class, there is no means to compiler can know in advance that KeyboardEvents<SnakeGame> will absolutely be extended by the class SnakeGame.
I mean, one could write this code:
KeyboardEvents<SnakeGame> keyboardEvents;
keyboardEvents.chooseMethodFromKeyboardArrows(/* some key */);
In that case, keyboardEvents is not related that much to SnakeGame. In fact there is no SnakeGame instance created at all! The compiler is right, the function chooseMethodFromKeyboardArrows that call direction is wrong to assume that a KeyboardEvents<SnakeGame> is a SnakeGame.
Inheritance work the other way around: a SnakeGame is indeed a KeyboardEvents<SnakeGame>. The other way is false.
I could show you how "to make it work", but a warning is needed here: you are overusing inheritance, and you used it the wrong way in the case of KeyboardEvent. You really should try to rearrange things around, or you'll end up in a real mess.
The solution "make it work"
Since you are using CRTP, you can tell the compiler that KeyboardEvents<SnakeGame> is indeed, in absolutely ALL cases, being extended by SnakeGame. If that's really the case, you can just static_cast your base class to the child class:
if(iterator!=mapOfDirects.end()){
// Notice the presence of the cast here
iterator->second->direction(static_cast<SnakeGame&>(*this));
mainDirection=codeFromKeyboard;
}
The slightly better solution
You can as well using an existing instance of your snake class as parameter.
void chooseMethodFromKeyboardArrows(sf::Keyboard::Key codeFromKeyboard, SakeGame& game){
auto iterator = mapOfDirects.find(codeFromKeyboard);
if(iterator!=mapOfDirects.end()){
iterator->second->direction(game);
mainDirection=codeFromKeyboard;
} else {
mapOfDirects[mainDirection]->direction(game);
}
}
However, the best idea is to not make SnakeGame extending KeyboardEvent, but to contain it in the class instead:
struct SnakeGame : Screen {
KeyboardEvent<SnakeGame> event;
void callEvents() {
event.chooseMethodFromKeyboardArrows(/* some key */, *this);
}
};
Here's an homework for you:
Try to make the class KeyboardEvent not a template. I'm sure you can find a way to pass around your class without the use of themplates, while still accessing directly to your class SnakeGame, without casts or interfaces.
Your design seems a bit overcomplicated. I think the reason this is so is perhaps you were designing it as you went along. Sometimes it helps to sit down and think about these things first, draw boxes and lines on a whiteboard if you have to.
In any case, this isn't a direct answer to your question, it's a suggestion for an alternative based on what I'm guessing you are trying to do.
It seems to me that you're trying to implement some generic keyboard input handler and tie it in to your game. It's possible that I'm entirely wrong about this, but if not, consider something like this instead. First, a generic interface for things that receive keyboard events. It need not be a template, this isn't really a good use-case for templates:
class KeyboardEventHandler {
public:
enum Direction { Left, Right, Up, Down };
virtual ~KeyboardEventHandler () { }
virtual void onDirectionKey (Direction d) = 0;
};
Now your SnakeGame, which handles keyboard events, can inherit that and implement its own SnakeGame-specific logic:
class SnakeGame : public KeyboardEventHandler {
public:
void onDirectionKey (Direction d) {
switch (d) {
case Up: ...
case Down: ...
case Left: ...
case Right: ...
}
}
};
And then whatever bit of code you have that is actually processing keyboard events and driving all of this can just work with a KeyboardEventHandler *, which could be a SnakeGame, or could be anything else you decide to use it for in the future.
That's just one possibility for organization. For example, you could structure it like this instead, breaking out the KeyboardEvent, which could simplify future additions:
class KeyboardEvent {
public:
enum Direction { Left, Right, Up, Down };
Direction getDirection () { ... } // or whatever
};
class KeyboardEventHandler {
public:
virtual ~KeyboardEventHandler () { }
virtual void onEvent (KeyboardEvent &event) = 0;
};
With SnakeGame as:
class SnakeGame : public KeyboardEventHandler {
public:
void onEvent (KeyboardEvent &event) {
...
}
};
You could name that stuff something else besides Direction / onDirectionKey if you want, I picked that from your example but just make it something semantically appropriate that is also convenient (e.g. if you plan on expanding it to include more than just the arrows). But whatever, that's beside the point.
There are also 10 zillion other ways to skin this cat but the important take-home point is: If you're trying to make some generic interface for something, you really can't make it rely on the specific details of what inherits it, otherwise you're defeating the purpose of making it general to begin with. In that case, either it's not a good case for generic bases / inheritance, or you've just botched the design and need to sit back and rethink.
Remember: Your goal isn't to add as many classes and stuff as possible to your code; you're not going for like, an inheritance high score. Your goal is to keep your code clean, readable, maintainable, correct, possibly reusable, and to make your work easier on yourself. These are tools, don't just use them because you have them, instead use them when you need them to make your life easier.
However, all that said, this is still overkill for your specific application, although it is an interesting exercise. To be honest, in your specific case, I'd just chuck all the inheritance and such altogether and do something like:
class SnakeGame {
public:
void handleKeyPress (char c) {
// ... do the right thing here
}
}
And be done with it.

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.