Thursday, February 19, 2015

Virtual Functions in C Language :

Virtual Functions :

Virtual functions let derived classes provide different versions of a base class function.
You can declare a virtual function in a base class , then redefine it in any derived class, even if the number and type of arguments are the same . The redefined function overrides the base class function.
You can also declare the functions

  int Base::Function(int)

and

  int Derived::Function(int)

even when they are not virtual.
When you declare virtual functions, keep these guidelines in mind:

    They can only be member functions.
    They can be declared a friend in another class.
    They cannot be a static member.

The base class version is available to derived class objects via scope override. If they are virtual, only the function associated with the actual type of
the object is available.
If two functions with the same name and have different arguments, C++ considers them different, and the virtual function mechanism is ignored.

virtual void gork(void) = 0;

is a pure virtual function. This makes the class an abstract type. gork() must be defined by derived classes or re-declared as pure.
Generally, when redefining a virtual function, you cannot change just the function return type. To redefine a virtual function, the new definition (in some
derived class) must exactly match the return type and formal parameters of the initial declaration. If two functions with the same name have different
formal parameters, C++ considers them different, and the virtual function mechanism is ignored.
However, for certain virtual functions in a base class, their overriding version in a derived class can have a return type that is different from the
overridden function. This is possible only when both of the following conditions are met:

    The overridden virtual function returns a pointer or reference to the base class.
    The overriding function returns a pointer or reference to the derived class.

If a base class B and class D (derived publicly from B) each contain a virtual function vf, then if vf is called for an object d of D, the call made is
D::vf(), even when the access is via a pointer or reference to B. For example,

struct X {};          // Base class.
struct Y : X {};      // Derived class.

struct B {
   virtual void vf1();
   virtual void vf2();
   virtual void vf3();
   void f();
   virtual X* pf();   /* Return type is a pointer to base. */
                      /* This can be overridden. */
   };

class D : public B {
public:
   virtual void vf1(); /* Virtual specifier is legal but redundant. */
   void vf2(int);      /* Not virtual, since it's using a different */
                       /* arg list. This hides B::vf2(). */

   // char vf3();
   // Illegal: return-type-only change!
   void f();
   Y*   pf();          /* Overriding function differs only  */
                       /* in return type. Returns a pointer */
                       /* to the derived class.             */
   };

    void extf() {
    D d;            /* Instantiate D */
    B* bp = &d;     /* Standard conversion from D* to B*             */
                    /* Initialize bp with the table of functions     */
                    /* provided for object d. If there is no entry   */

                    /* for a function in thed-table, use the         */
                    /* function in the B-table.                      */
    bp->vf1();      /* Calls D::vf1 */
    bp->vf2();      /* Calls B::vf2 since D's vf2 has different args */
    bp->f();        /* Calls B::f (not virtual)                      */

          X* xptr = bp->pf();   /* Calls D::pf() and converts the result
                                   to a pointer to X. */

       D* dptr = &d;
       Y* yptr = dptr->pf();  /* Calls D::pf() and initializes yptr. */

                              /* No further conversion is done.      */
       }

The overriding function vf1 in D is automatically virtual . The virtual specifier can be used with an overriding function declaration in the derived class. If other classes will be derived from D, the virtual keyword is required . If no further classes will be derived from D, these of virtual is redundant.
The interpretation of a virtual function call depends on the type of the object it is called for; with nonvirtual function calls, the interpretation depends only on the type of the pointer or reference denoting the object it is called for .
virtual functions exact a price for their versatility: each object in the. derived class needs to carry a pointer to a table of functions in order to select the correct one at run time (late binding) .


No comments:

Post a Comment