Polymorphism

 

Inheritance

Pointer Rules

Binding

                    void Shape :: error ( ) const
                        { cerr << ObjectType ( ) << " error!" << endl; }

                    string Shape :: ObjectType ( ) const
                        { return "Shape" ; }

                    class Circle : public Shape
                    {
                        public:
                                void draw ( ) const;  // must implement so can instantiate
                                string ObjectType ( ) const;  // override Shape :: ObjectType ( )
                        // Both methods implicitly virtual (since virtual in Shape)

                    };

                    void Circle :: draw ( ) const
                        {   /* implement drawing a circle */ };

                    string Circle :: ObjectType ( ) const
                        { return "Circle"; }

                    class Rectangle : public Shape
                    {
                        public:
                                void draw ( ) const; // must implement so can instantiate
                                string ObjectType ( ) const; // override Shape :: ObjectType ( )
                    };

                    void Rectangle :: draw ( ) const
                        {  /* implement drawing a rectangle */ };

                    string Rectangle :: ObjectType ( ) const
                        {  return "Rectangle"; }
 

                    class Triangle : public Shape
                    {
                        public:
                                void draw ( ) const; // must implement so can instantiate
                                string ObjectType ( ) const; // override Shape :: ObjectType ( )
                    };

                    void Triangle :: draw ( ) const
                        {  /* implement drawing a triangle */ };

                    string Triangle :: ObjectType ( ) const
                        {  return "Triangle"; }

                   void main ( )
                    {
                        Shape* s1 = new Circle ( );  // static: Shape*, dynamic: Circle*
                        Shape* s2 = new Rectangle ( ); // static: Shape*, dynamic: Rectangle*
                        Shape* s3 = new Triangle ( ); // static: Shape*, dynamic: Triangle*

                        s2 -> draw ( );   // Rectangle :: draw ( )
                        s1 -> error ( );   // Shape :: error ( ), calls Circle :: ObjectType ( )
                        cout << s3 -> ObjectType ( );  // Triangle :: ObjectType ( )

                        Shape* array[3] = { new Rectangle ( ), new Circle ( ), new Triangle ( ) };
                        for ( int i=0; i<3; i++ )
                            array [ i ] -> draw ( );     // calls correct method for each element
                      }

Polymorphic Functions

void drawShape ( Shape* p )  // pass via pointer
{
    cout << "drawShape called on: " << p -> ObjectType ( ) << endl;
        // always prints correct type name; ObjectType is virtual function!
    p -> draw ( );  // automatically calls function for correct type
    if ( /* error condition */ )
        p -> error ( );  // calls Shape :: error ( ), non virtual
                               //  but that calls correct virtual ObjectType
}

void drawShape ( Shape& p )  // pass via reference
{
    cout << "drawShape called on: " << p . ObjectType ( ) << endl;
        // always prints correct type name; virtual function!
    p . draw ( );  // automatically calls function for correct type
    if ( /* error condition */ )
        p . error ( );  // calls Shape :: error ( ), non virtual
                            //  but that calls correct virtual ObjectType
}

this and virtual functions

Code Dependence

Pass-by-value Restrictions

When function parameters are passed by value:

Slicing

Polymorphism and Destructors

Designing Hierarchical Classes