Topic : Polymorphism
Author : Donovan Rebbechi
Page : 1 Next >>
Go to page :


Polymorphism



Abstract
Runtime polymorphism in C++ is a challenging topic that is often not well understood by beginners, and indeed, by the authors of some C++ text books! This is a pity, as runtime polymorphism is without a doubt an essential component of any object oriented system. In fact some would use runtime polymorphism as a definition of OO. But others would not. The debate over the ``true'' definition of OO is an example of a holy war .

Introduction
In languages that are weakly typed, runtime polymorphism is very easy to understand. For example, in perl, if $a is an object reference of type Foo, it's pretty obvious that $a->f() is going to call the f method defined for class Foo, because perl references do not contain any type information besides the name of the package they belong to.

However, in strongly typed languages, it gets rather confusing, because types must be explicitly decided at compile time. Every object we declare contains type information, which must be available at compile time. But despite the apparent rigidity of strong typing, there is actually some room to move:

    -> Base class pointers are allowed to point to derived class objects, and base class references are allowed to refer to derived class objects. In particular,

    The type of a pointer (or reference) needs to be known at compile time, but the type of the derived object it points to (or refers to) does not. We only need know that it's a derived class object.

   ->It gets better. The only objects whose type must be known at compile time are the objects we declare. This leaves room for anonymous objects -- unnamed objects that are used via pointers. The type of the pointer must be known at compile time, but we can create something for it to point to dynamically at runtime. For example, consider this segment of code (assume that Square, Circle and Triangle are derived from Shape )
Shape* x;
int a = rand()/(RAND_MAX+1.0)*3; // random number from 0-2
switch (a)
{
   case 0:
      x = new Square;
      break;
   case 1:
      x = new Triangle;
      break;
   case 2:
      x = new Circle;
      break;
   default:
      x = 0;
}

x-> draw();


         

An Example
It should be clear that this enables us to randomly create different types of shapes, and the decision is truly deferred until runtime. We follow up with a complete example:


#include <iostream>
#include <list>

class Shape
{
public:
    virtual void draw() = 0;
    virtual ~Shape() = 0;
protected:
    Shape(){}
    Shape(const Shape&){}
    Shape& operator=(const Shape&) { return *this; }
};

Shape::~Shape(){}

class Circle : public Shape
{
public:
    virtual void draw()
    {
        std::cout
            <<  "           ****         \n"
            <<  "        *        *      \n"
            <<  "      *            *    \n"
            <<  "     *              *   \n"
            <<  "     *              *   \n"
            <<  "     *              *   \n"
            <<  "     *              *   \n"
            <<  "      *            *    \n"
            <<  "        *        *      \n"
            <<  "           ****         \n"
            << std:: endl;
    }
    virtual ~Circle(){}
};

class Triangle : public Shape
{
public:
    virtual void draw()
    {
        std::cout
            <<  "     |\\               \n"
            <<  "     |+\\              \n"
            <<  "     |= \\             \n"
            <<  "     |= =\\            \n"
            <<  "     |== =\\           \n"
            <<  "     |== ==\\          \n"
            <<  "     |== ===\\         \n"
            <<  "     |==    =\\        \n"
            <<  "     |=  +++==\\       \n"
            <<  "     |=+  +====\\      \n"
            <<  "     |== +     =\\     \n"
            <<  "     |=+       ==\\    \n"
            <<  "     L____________\\   \n"
            << std:: endl;
    }
    virtual ~Triangle(){}
};

class Square: public Shape
{
public:
    virtual void draw()
    {
        std::cout
            <<  "      ______________    \n"
            <<  "     |/             |   \n"
            <<  "     |//  ====      |   \n"
            <<  "     |///       ====|   \n"
            <<  "     |/////         |   \n"
            <<  "     |//===         |   \n"
            <<  "     |////========  |   \n"


Page : 1 Next >>