3

I'm trying to understand a polymorphism but I don't understand why we need runtime polymorphism if static polymorphism works fine for calling members of a class.

Like, suppose this was a problem.

#include <bits/stdc++.h>
using namespace std;
class base{
    public:
        virtual void fun(){
            cout<<"base called"<<endl;
        }
};
class derived:public base{
    public:
        void fun(){
            cout<<"derived called"<<endl;
        }
};
int main() {

    base b,*b1;
    derived d;
    b1 = &d;
    b1->fun();
    // b.fun();
    // d.fun();
}

suppose this was my code and I want to access the function of derived or base class and I was able to do it by simply creating an object of that class so if there is no problem then why we try to call the object using references (runtime polymorphism). Can someone explain the actual need for runtime polymorphism or if it is possible can you explain it by using any real-life scenarios??

  • I hope this helps: https://stackoverflow.com/questions/14953222/are-virtual-functions-the-only-way-to-achieve-runtime-polymorphism-in-c/14953419 – Harsh Thakkar May 31 '20 at 07:50
  • 3
    [Why should I not #include ?](https://stackoverflow.com/q/31816095/1362568) – Mike Kinghan May 31 '20 at 07:57
  • Look at `void f(base* b) { b->fun(); }`. Which function does it call? – molbdnilo May 31 '20 at 08:12
  • Shivam: Doesn't any of the answers answer your question? Please read [What should I do when someone answers my question?](https://stackoverflow.com/help/someone-answers) – Ted Lyngmo Jun 15 '20 at 09:50

3 Answers3

2

Suppose you have a library which has a class and few methods which takes a pointer to that class.

class GameObject {

public:
    virtual void print_to_display(void);

};

class Game {

public:
    void add_obj(GameObject *obj);
};

Since, you just have the library (shared library and few header files) and you don't want to modify the libraries source code (as it may break existing method).

You can extend the class GameObject in your project and override it's print method to do something other than the default behavior.

class MyObject: public GameObject {

public:
    void paint(void) override;
};
abhiarora
  • 7,515
  • 3
  • 27
  • 46
2

Polymorphism is useful any time that the software can't be told at compile time exactly what everything is going to be at runtime, or when you need a container to be able to hold a heterogeneous assortment of things that all implement a common interface.

A good example is UI toolkits. Pretty much all UI toolkits have a concept of a container that can hold other widgets, but the UI toolkit author has no idea what widgets you are going to put into the container. Since the container needs to be able to deal with any kind of widget, polymorphism is the easiest way to achieve this.

cdhowie
  • 133,716
  • 21
  • 261
  • 264
2

Polymorphism is considered as one of the important features of Object-Oriented Programming. In C++ polymorphism is mainly divided into two types:

  • Compile-time Polymorphism: This type of polymorphism is achieved by function overloading or operator overloading.

  • Runtime Polymorphism: This type of polymorphism is achieved by Function Overriding.

Now consider the following scenario.

Suppose we have a base class named Shape which has the following interface.

class Shape {
public:
    Shape(int init_x, int init_y);
    virtual ~Shape() = default;

    virtual void scale(int s) = 0;
protected:
    int x;
    int y;
};

Now we want to inherit two other classes named Rectangle and Circle from it.

class Rectangle : public Shape {
public:
    Rectangle(int init_x, int init_y, int w, int h);
    void scale(int s) override;
private:
    int width;
    int height;
};
class Circle : public Shape {
public:
    Circle(int init_x, int init_y, int r);
    void scale(int s) override;
private:
    int radius;
};

As you may know, circle and rectangle shapes, have different implementation for their scale method, so I can't implement that in the Shape class.

Now suppose we have a program that stores all the shapes in a container like vector<Shape*> (e.g. it gets all the shapes from the user once and store them in this container).

If we want to use scale method on one of the shapes, we don't know actually which kind of shape we are dealing with, but it will bind our scale method call to its appropriate implementation.

Ted Lyngmo
  • 37,764
  • 5
  • 23
  • 50
Mohammad Moridi
  • 148
  • 1
  • 8
  • I'm pretty much got your point but as you say that "we don't know actually which kind of shape we are dealing with" so why we are doing this step for calling a function of particular derived class. ` base b,*b1; derived d; b1 = &d; // this step basically` – Shivam Jain May 31 '20 at 11:34
  • @ShivamJain Suppose you have some other classes like `Rectangle` and `Circle` (e.g. `Square`, `Triangle` and etc.). If you do not want to collect them all in one container (e.g. `vector`), you have to have multiple containers that each of them contains a specific type of shape. Actually polymorphism adds a **level of abstraction** in your design which is one of the most important principles to have a good design. – Mohammad Moridi Jun 01 '20 at 06:32
  • 1
    I recommend using `void scale(int s) override;` in the derived classes instead of `virtual void scale(int s);`.to get a compile-time error if it doesn't override a `virtual` method as it's supposed to do and I made that change to the answer. I also added a virtual destructor to the base class so you can `delete` objects through a base class pointer. – Ted Lyngmo Jun 15 '20 at 10:26