Suppose that you have the following scheme:
class Base {
public:
virtual int foo() = 0;
};
class Derived1 : public Base {
public:
virtual int foo() { return 1; }
};
class Derived2 : public Base {
public:
virtual int foo() { return 2; }
};
Lets say now, that you want to store objects of Derived1
and Derived2
in a container, lets say a std::vector
and every time you iterate through the vector to call for each one of its objects function foo
. Normally, you'd need two vectors, one for objects of class Derived1
and another one for objects of class Derived2
.
Look now how polymorphism comes to our rescue. We can store the addresses of objects Derived1
and Derived2
as pointers to Base
objects, and then store these pointers in a std::vector<Base*> v
. Now every time we iterate the vector of pointers and call member function foo
(e.g., for(auto base : v) base->foo()
) the right function foo
is called for each one of the objects. This is one of the many aspects of polymorphism which is called upcasting
I hope that the above example of runtime polymorphism gave you a clue, as for how virtual functions and function overriding are related to inheritance and polymorphism.
Update:
Templates are a form of compile time polymorphism take a look at this SO question what is the difference between templates and polymorphism.