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?
CodePudding user response:
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:
- I also declared the destructor virtual. This allows for proper destruction of an object through its base class pointer.
- I declared the base
draw
method as pure-virtual (the= 0
part). This means thePolygon
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. - 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.
CodePudding user response:
You need to define the function as virtual in the base class and the override it in the subclasses. For example
#include <vector>
#include <iostream>
struct A{
virtual void p(){std::cout<<"A ";}
A(){}
virtual ~A() {};
};
struct B: public A{
void p()override{std::cout<<"B ";}
B(): A(){}
};
struct C: public A{
void p()override{std::cout<<"C ";}
C() : A(){}
};
int main()
{
A* a=new A();
B* b=new B();
C* c=new C();
std::vector<A*> v={a,b,c};
for(auto i : v)
i->p();
std::cout<<"\n";
delete a;
delete b;
delete c;
return 0;
}
prints "A B C".