0

I am trying to implement polymorphism, so I can expand my project later with minimal refactoring. I am also attempting to implement the Command pattern from this book (https://gameprogrammingpatterns.com/command.html).

Desired outcome: My most derived classes implementation of virtual functions are called through a std::shared_ptr<Base>(Most_Derived_Class). If this is the wrong syntax, I want to handle my most derived class through a shared pointer to one of its base classes.

Current outcome: Base class implementations of virtual functions are called through the pointer mentioned in desired outcome.

Here is a runnable, simplified version of my code:

#include <iostream>
#include <vector>
class Base
{
public:
    Base()
    {

    }

    void virtual update()
    {
        std::cout << "no update function\n";
    }
    void virtual draw()
    {
        std::cout << "no draw function\n";
    }
};

class Derived : public Base
{
public:
    Derived();
    void draw() override;
    void update() override;
};

Derived::Derived()
{
    
}

void Derived::draw()
{
    std::cout << "Derived Draw Called\n";
}

void Derived::update()
{
    std::cout << "Derived Update Called\n";
}

class Second_Derived : public Derived
{
public:
    Second_Derived() {}
    virtual void move_up() { std::cout << "Second_Derived Move_Up called\n"; };
};

class Third_Derived : public Second_Derived
{
public:
    Third_Derived();
    ~Third_Derived();

    void move_up() override;

    void draw() override;
    void update() override;
};

Third_Derived::Third_Derived() {}
Third_Derived::~Third_Derived() {}

void Third_Derived::move_up()
{
    std::cout << "Third Derived Move_Up called\n";
}

void Third_Derived::draw()
{
    std::cout << "Third Derived draw called\n";
}

void Third_Derived::update()
{
    std::cout << "Third Derived update Called\n";
}

class Command
{
public:
    virtual void execute(Second_Derived s_derived) { std::cout << "Base Command execute called\n"; }
};

class Move_Up : public Command
{
public:
    Move_Up() {}

    void execute(Second_Derived s_derived) override
    {
        std::cout << "Move_Up called\n";
        s_derived.move_up();
    }
};

class Input_Handler
{
public:
    Input_Handler() {};
    Command* handle_input()
    {
        return &return_command;
    }

private:
    Move_Up return_command;
};


class Caller
{
public:
    Caller();

    void update();
    void draw();

    void reg_obj(std::shared_ptr<Second_Derived> obj);
private:
    void process_inputs();
    Input_Handler i_handler;
    std::vector<std::shared_ptr<Second_Derived>> all_objects;
};

Caller::Caller()
{
    Third_Derived third_derived_class{};
    reg_obj(std::make_shared<Second_Derived>(third_derived_class));
}

void Caller::process_inputs()
{
    Command* current_inputs = i_handler.handle_input();
    if (current_inputs)
    {
        current_inputs->execute(*all_objects[0]);
    }
}

void Caller::update()
{
    process_inputs();
    for (int i = 0; i < all_objects.size(); i++)
    {
        all_objects[i]->update();
    }
}

void Caller::draw()
{
    for (int i = 0; i < all_objects.size(); i++)
    {
        all_objects[i]->draw();
    }
}

void Caller::reg_obj(std::shared_ptr<Second_Derived> obj)
{
    all_objects.push_back(obj);
}

int main()
{
    Caller caller{};

    while (true)
    {
        caller.update();
        caller.draw();
    }
}

Bonus: If you can recommend me solid (ideally free) C++ polymorphism resources, because this is my second run-in with polymorphism issues, and it's pretty clear to me that I need to do more reading on it.

Sage King
  • 1
  • 3
  • For polymorphism to work you need *pointers* or *references* to a common base class. When you do `current_inputs->execute(*all_objects[0])` you loose the possibility to use polymorphism. – Some programmer dude Aug 13 '21 at 14:21
  • `Move_Up::execute` takes the object by value causing object slicing, change it to take a reference instead – Alan Birtles Aug 13 '21 at 14:23

0 Answers0