Search code examples
c++oopinheritanceoverridingstdvector

Calling overridden methods from a vector of superclass pointers


I am currently writing a small game in OpenGL using C++. Coming from a non-C++ background, I have a simple question about overriding methods and how to call them using a pointer of a superclass type.

This is the case: I have a class Polygon containing the method void draw(). This class has two children called Rectangle and Circle, which both override the drawing method, as I am using different OpenGL calls depending on the type of polygon being drawn.

Now consider this: I wish to store all polygons (including both rectangles and circles) in an std::vector<Polygon*>. This is perfectly fine. However, iterating through the vector and calling draw automatically resorts to the superclass' version of the method.

How can I make a vector of type superclass-pointer, store pointers to subclass objects in it, and call overridden functions depending on the actual type of the object being used?


Solution

  • You are describing polymorphism (or a lack thereof in your current implementation).

    To make your draw function polymorphic, you must declare it virtual. See below for an example:

    class Polygon {
    public:
        virtual ~Polygon() {}
        virtual void draw() = 0;
    };
    
    class Rectangle : public Polygon
    {
    public:
        void draw() override { std::cout << "Rectangle::draw()\n"; }
    };
    
    class Circle : public Polygon
    {
    public:
        void draw() override { std::cout << "Circle::draw()\n"; }
    };
    

    Note three extra things in the above:

    1. I also declared the destructor virtual. This allows for proper destruction of an object through its base class pointer.
    2. I declared the base draw method as pure-virtual (the = 0 part). This means the Polygon class is abstract and cannot itself be instantiated. You may not want that, but to me it seems there's no use for a draw method on a base class anyway. Define one if you want. Up to you.
    3. The override specifier is optional, but recommended (language feature introduced by C++11). It instructs the compiler that you're intentionally overriding a virtual method, and so if no such method exists to be overridden then it will generate a compiler error.