Important feature in C++ : Polymorphism

Started by sukishan, Jul 10, 2009, 10:10 PM

Previous topic - Next topic

sukishan

Polymorphism

Polymorphism is the technique of defining a common interface for a hierarchy of classes. To support this, a derived object is allowed wherever a base object is expected. For example,

  String s="Hello";
  Vector<char> v=s;    // Discards derived part of s to convert
  Vector<char>* p=&s;  // p points to base part of s
  try {throw s;} catch(Vector<char> x) {}  // Caught with x set to base part of s
  s=Vector<char>(5);   // Error, can't convert base to derived

  // Allow output of Vector<char> using normal notation
  ostream& operator << (ostream& out, const Vector<char>& v) {
    copy(v.begin(), v.end(), ostream_iterator<char>(out, ""));  // Print v to out
    return out;        // To allow (cout << a) << b;
  }
  cout << s;           // OK, v refers to base part of s
  ofstream f("file.txt");
  f << s;              // OK, ofstream is derived from ostream

A derived class may redefine inherited member functions, overriding any function with the same name, parameters, return type, and const-ness (and hiding other functions with the same name, thus the overriding function should not be overloaded). The function call is resolved at compile time. This is incorrect in case of a base pointer or reference to a derived object. To allow run time resolution, the base member function should be declared virtual. Since the default destructor is not virtual, a virtual destructor should be added to the base class. If empty, no copy constructor or assignment operator is required. Constructors and = are never virtual.

  class Shape {
  public:
    virtual void draw() const;
    virtual ~Shape() {}
  };
  class Circle: public Shape {
  public:
    void draw() const;      // Must use same parameters, return type, and const
  };

  Shape s; s.draw();        // Shape::draw()
  Circle c; c.draw();       // Circle::draw()
  Shape& r=c; r.draw();     // Circle::draw() if virtual
  Shape* p=&c; p->draw();   // Circle::draw() if virtual
  p=new Circle; p->draw();  // Circle::draw() if virtual
  delete p;                 // Circle::~Circle() if virtual

An abstract base class defines an interface for one or more derived classes, which are allowed to instantiate objects. Abstractness can be enforced by using protected (not private) constructors or using pure virtual member functions, which must be overridden in the derived class or else that class is abstract too. A pure virtual member function is declared =0; and has no code defined.

  class Shape {
  protected:
    Shape();                 // Optional, but default would be public
  public:
    virtual void draw() const = 0; // Pure virtual, no definition
    virtual ~Shape() {}
  };
  // Circle as before

  Shape s;                   // Error, protected constructor, no Shape::draw()
  Circle c;                  // OK
  Shape& r=c; r.draw();      // OK, Circle::draw()
  Shape* p=new Circle();     // OK
A good beginning makes a good ending