Search code examples
c++functioninheritancevectorvirtual

How to create a vector of objects which inherit from the same base classes and have unique functions?


I want to create vector of objects which inherit from the same base class but have their own functions, which are not in the base class (creating virtual function is not possible, because the classes which inherit take in different variables as parameters of a function).

Base class: Model

First class which inherits from Model class: Bus

void Bus::draw_model_bus(angle_x, angle_y, P_scene, V_scene, M_scene) const;

Second class which inherits from Model class: Grass

void Grass::draw_model_grass(P_scene, V_scene, M_scene) const;

... and I want to make it possible to call above functions on Bus and Grass objects which are stored in this one vector of models. std::vector<Model*> models; Code below doesn't work:

    models[0]->draw_model_bus(angle_x, angle_y, P_scene, V_scene, M_scene);
    models[1]->draw_model_grass(P_scene, V_scene, M_scene);

I wanted to initialize these objects like this:

    // Bus
    models.emplace_back(Bus("res/models/Bus.obj", "res/textures/Bus_tex.tga.png"));
    models[0]->read_model();
    
    // Grass
    models.emplace_back(Grass("res/models/grass.obj", "res/textures/grass.png"));
    models[1]->read_model();

How to make it possible to store these object like I described above?


Solution

  • I'm afraid what you want to achieve is not possible in a simple way. That is because the C++ mechanisms you are trying to use were not designed to be used in such a way.

    Inheritance - you would use it if:

    • you want to reuse the interface, which seems not to be the case here, because you want different function names;
    • or, you'd want to reuse the implementation, aka common code which is already present in the base class.

    In order to workaround your problem with different parameters, you could encapsulate those into a wrapper object, which can be created either from the first or the second set. Something like this:

    class Input {
    public:
     Input(int angle_x, int angle_y, int P_scene, int V_scene, int M_scene);
     Input(int P_scene, int V_scene, int M_scene);
     ...
    };
    
    
    class Model {
    public:
      virtual void draw(const Input& in);
      ...
    };
    
    class Bus: public Model {
    public:
      void draw(const Input& in) override;
      ...
    };
    
    class Grass: public Model {
    public:
      void draw(const Input& in) override;
      ...
    };
    
    int main() {
        std::vector<Model*> models;
        ...
        models[0]->draw(Input(angle_x, angle_y, P_scene, V_scene, M_scene));
        models[1]->draw(Input(P_scene, V_scene, M_scene));
    }