Emailid
Password
         
  
    Forgot password

New user Sign Up
 

C++ and Polymorphism

       Current Rating:  0%                                                     Total Members Rated:  0
                                                                     Send To Friend

  

C++ and Polymorphism

 

 

Polymorphism

 

It is the ability to call different functions by just using one type of function call. In selecting the appropriate member function to call in response to a function invocation, C++ distinguishes between the static type of a reference and the dynamic type of the object it refers to at a given point. The dynamic type must be a descendant of the static type.  The invocation is type-checked based on the static type of the reference. If the function called is a virtual member function, the member function associated with the actual object pointed to is called dynamically at run time. If the function is non-virtual, the call will have been statically bound to the member function of the reference's class at accumulate occasion.

 

Uses



1. It is a lot useful since it can group classes and their functions together.

 

2. It is the most important part of Object-Oriented Programming.

 

3. Polymorphism is the core of object-oriented programming .

 

4. C++ supports polymorphism by allowing member functions defined in classes to be overridden with member functions having the same names, but different implementations, in derived classes.

 

5. Polymorphism allows an entity (for example, variable, function or object) to take a variety of representations. Therefore we have to distinguish different types of polymorphism which will be outlined here.

 

Type one

 

The first type is similar to the concept of dynamic binding. Here, the type of a variable depends on its content. Thus, its type depends on the content at a specific time:

 

 

v := 123        /* v is integer */

...             /* use v as integer */

v := 'abc'      /* v "switches" to string */

...             /* use v as string */

 

Type two

 

 

 

Another type of polymorphism can be defined for functions. For example, suppose you want to define a function isNull() which returns TRUE if its argument is 0 (zero) and FALSE otherwise.

For integer numbers this is easy:

return FALSE

else

return TRUE

if (a == 0) then

{

boolean isNull(int a)

endif

}

 

If we want to check this for real numbers, we should use another comparison due to the precision problem:

 

boolean isNull(real x)

{

if (x < 0.01 and x > -0.99) then

return TRUE

else

return FALSE

endif

}

 

For the above cases we want the function to have the name is Null. In programming languages without polymorphism for functions we cannot declare these two functions because the name is Null would be doubly defined. Without polymorphism for functions, doubly defined names would be ambiguous. However, if the language would take the parameters of the function into account it would work.



Thus, functions (or methods) are uniquely identified by  the name and the types of its parameter list.

The compiler is able to figure out the correct function call by using the actual types of the arguments since the parameter list of both is Null functions differ:

 

var a : integer

var x : real

a = 0

x = 0.0

...

if (isNull(a)) then ...   /* Use isNull(int) */

...

if (isNull(x)) then ...   /* Use isNull(real) */

 

When a method is defined by the combination of its name and the list of types of its parameters.

We can say polymorphism. This type of polymorphism allows us to reuse the same name for functions (or methods) as long as the parameter list differs. Sometimes this type of polymorphism is called overloading.

The last type of polymorphism allows an object to choose correct methods. Consider the function move() again, which takes an object of class Point as its argument. We have used this function with any object of derived classes, because the is-a relation holds.

Now consider a function display() which should be used to display drawable objects. The declaration of this function might look like this:

 

display(DrawableObject o)

{

...

o.print()

...

}

Use this function with objects of classes derived from DrawableObject:
Circle acircle
Point apoint
Rectangle arectangle

display(apoint) /* Should invoke apoint.print() */
display(acircle) /* Should invoke acircle.print() */
display(arectangle) /* Should invoke arectangle.print() */

The actual method should be defined by the content of the object o of function display().

Since this is somewhat complicated, here is a more abstract example:

class Base {

attributes:

methods:

virtual f ()

funy()

}

 

class Derived inherits from Base {

attributes:

methods:

virtual funx ()

funy()

}

demo(Base o) {

o.funx ()

o.funy()

}

Base abase

Derived aderived

demo(abase)

demo(aderived)

 

Here we define two classes Base and Derived. Each class defines two methods funx() and funy(). The first method is defined as virtual. This means that if this method is invoked its definition should be evaluated by the content of the object.

Then define a function demo() which takes a Base object as its argument. Consequently, we can use this function with objects of class Derived as the is-a relation holds. We call this function with a Base object and a Derived object, respectively.

Assume, that funx() and funy() are defined to just print out their name and the class in which they are defined.

Then the output is as follows:
funx() of Base called.
funy() of Base called.
funx() of Derived called.
funy() of Base called.

 

Conclusion

The first call to demo() uses a Base object. Thus, the function's argument is ``filled'' with an object of class Base. When it is time to invoke method funx() it's actual functionality is chosen based on the current content of the corresponding object o. This time, it is a Base object. Consequently, funx() as defined in class Base is called. The call to funy() is not subject to this content resolution. It is not marked as virtual. Consequently, funy() is called in the scope of class Base.

The second call to demo() takes a Derived object as its argument. Thus, the argument o is filled with a Derived object. However, o itself just represents the Base part of the provided object aderived.  Now, the call to funx() is evaluated by examining the content of o, hence, it is called within the scope of Derived. On the other hand, funy() is still evaluated within the scope of Base.

 

All the best!


                           Rate This Article:   

Author is Offline
  Author: Zebastti Tottileit
       


Comments Posted
Label
Subject Author Status Date

 

Post Comment

Related Articles
Fundamentals on .NET Framework
N-Tier in ASP.NET or other .NET apps
Software Development Outsourcing (Offshore ) to India
Make your web site ‘perfect and Search Engine Friendly for Google and Yahoo
Color combination of your Web site



Home | About Us | Site Map | Privacy Policy | Submit Links