Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 410
Ashutosh Sharma Avatar asked Feb 19 '13 08:02

Ashutosh Sharma


People also ask

Which function is used to achieve runtime polymorphism?

Virtual function: Virtual functions are mainly used to achieve runtime polymorphism.

Can we achieve runtime polymorphism by virtual function?

The main use of virtual function is to achieve Runtime Polymorphism. Runtime polymorphism can be achieved only through a pointer (or reference) of base class type. Also, a base class pointer can point to the objects of base class as well as to the objects of derived class.

Can we achieve polymorphism in C?

There's no intrinsic support for polymorphism in C, but there are design patterns, using function pointers, base 'class' (structure) casts, etc., that can provide a logical equivalent of dynamic dispatch.

Is virtual function a form of polymorphism?

A virtual function is a special type of function that, when called, resolves to the most-derived version of the function that exists between the base and derived class. This capability is known as polymorphism.


2 Answers

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.

like image 129
Alok Save Avatar answered Sep 24 '22 04:09

Alok Save


The C language's fprintf is a polymorphic function.

You can pass it various handles and it can print to a file, stdout, a printer, a socket, anything which the system can represent as a stream.

FILE* file = fopen("output.txt", "w");                    // a file
FILE* file = stdout;                                      // standard output
FILE* file = fopen("/dev/usb/lp0", "w");                  // a usb printer
FILE* file = popen("/usr/bin/lpr -P PDF", "w");           // a PDF file
FILE* file = fdopen(socket(AF_INET,SOCK_STREAM,0), "r+"); // network socket

fprintf(file, "Hello World.\n");
like image 29
Peter Wood Avatar answered Sep 23 '22 04:09

Peter Wood