C++ – Are virtual functions the only way to achieve Runtime Polymorphism in C++

cpolymorphism

One of my friends asked me "How Runtime Polymorphism is achieved in C++?" I answered "By Inheritance"

He said "No, it can be achieved only using virtual functions".

So I gave him an example of the following code :-

#include<iostream>
using namespace std;

class A
{
public:
    int i;
    A(){i=100;}
};

class B : public A
{
public:
    int j;
    B(){i = -1; j = 99;}
};

void func(A& myA)
{
    cout<<myA.i << endl;
}

int main()
{
    B b;
    A* a = new B();
    func(*a);
    func(b);
    delete a;
    return 0;
}

Here, function func() takes reference of A but we pass object of B and we can print the value of public member "i". He said it is compile time polymorphism.

My questions are :-

1) Is Runtime polymorphism achieved only with virtual functions?

2) Is the example above has runtime polymorphism or compile time?

3) If I have the following code :-

void func2(A& myA)
{
    cout << myA.i << endl;
    // dynamic/static cast myA to myB
    cout<<myB.j << endl;
}

what kind of polymorphism is it? Or is it even polymorphism?

Best Answer

The example does not show dynamic polymorphism. The method to be called is known at compile time. There is no runtime decision(based on actual object type) as to which method should be called. There is no different behavior for different types.

For the example to be example of dynamic polymorphism.
You need to provide a virtual member function in Base class and overide it in derived class. The actual method to be called is decided by the actual type of the object pointed by the Base class pointer.

Online sample:

#include<iostream>
using namespace std;

class A
{
public:
    virtual void doSomething()
    {
        std::cout<<"\nIn A::doSomething()";
    }
};

class B : public A
{
public:
    virtual void doSomething()
    {
        std::cout<<"\nIn B::doSomething()";
    }
};



int main()
{
    B b;
    A obj;
    A* a = &b;
    a->doSomething();

    a = &obj;
    a->doSomething();

    return 0;
}

Output:

In B::doSomething()
In A::doSomething()

Is Runtime polymorphism acheived only with virutal functions?

No, but virtual functions is the most common and correct way to do so.
Polymorphism can be achieved through function pointers. Consider the following code example, the actual method to call is decided at run-time depending on user input. It is a form of polymorphism through not in strict sense C++ sense which mandates different behaviors for different types.

#include <iostream>

typedef void (*someFunction)(int, char*);

void FirstsomeFunction(int i, char *c)
{
    std::cout<<"\n In FirstsomeFunction";
}

void SecondsomeFunction(int i, char *c)
{
    std::cout<<"\n In SecondsomeFunction";
}

int main()
{
    someFunction arr[1];
    int x = 0;
    std::cin >> x;

    if(x ==0)
        arr[0] = &FirstsomeFunction;
    else
        arr[0] = &SecondsomeFunction;

    (arr[0])(10,"Hello");

    return 0;
}

Is the example above has runtime polymorphism or compile time?

There is no polymorphism of any kind. The same method will be called in all cases. There is no different behavior for different types and hence it does not classify as polymorphism of any kind.