Polymorphism and Virtual functions _Cont._

Document Sample
Polymorphism and Virtual functions _Cont._ Powered By Docstoc
					     Inheritance and
Polymorphism: Part 2
           BCA Sem III
What is the need for Inheritance?

There are basically 2 reasons for the
  introduction of the concept of inheritance:
1) Reusability (the new derived classes can
  use the features of base classes )
 2) Transitive nature of inheritance : it can
  be passed on further
Visibility modes
 It can be public, protected or private .The private data in base class
   cannot be inherited
 Public: In public mode the public members of the base class
   become public in derived class and protected members become
   protected in the derived class
 Private: In private mode the public members of the base class
   become private in derived class and protected members become
   private in the derived class
 Protected: In protected mode the public members of the base class
   become protected in derived class and protected members become
   protected in the derived class
 In case we write something like:
Class derived :base //private derivation mode by default
{ //       };
When we say that the members of a class are inheritable , it means
   the derived class can access them directly. However the derived
   class only have access to the non-private members of the base
   class . Although the private members of the base class cannot be
   accessed directly, yet the objects of the derived class are able to
   access them through the non-private inherited members
    Public visibility mode
                                                            Class marks
Class student                      Class student
{ private:
    int x;
                                           private                private
   void getdata();
   public:                              x       getdata()   a       readdata()
   int y;
   void putdata();
    int z;
    void check();                                                 Public
};                                          public                     putdata()
Class marks :public student           y       putdata()
{ private:                                                   b         writedata()
    int a;
   void readdata();
   public:                                                       Protected
   int b;
   void writedata();                      protected          c      checkvalue()
                                     z           check()
    int c;                                                   z        check()
    void checkvalue();
};                     Inherited from student class
    Private visibility mode
                                                                  Class marks
class student                    Class student
{//same                                                                 Private
};                                               private           a         readdata()
class marks: private student               x          getdata()
                                                                   y            putdata()
};                                                                 z             check()
                                       y           putdata()
                                                                   b        writedata()

                                                      check()          Protected

                                                                   c      checkvalue()

                          Inherited from student class
    Protected visibility mode
                                                           Class marks
                                 Class student
class student
{//same                                                          Private
                                            private         a
};                                                                    readdata()
class marks: protected student      x          getdata()
};                                                               Public
                                             public        b       writedata()
                                    y          putdata()

                                            Protected           Protected
                                        z                   c      checkvalue()

                                                            y      putdata()

                                                            z       check()
                         Inherited from student class
    What is Run Time Polymorphism
 Run time polymorphism (implemented in C++ with virtual functions) is the thir
  essential feature of an object oriented programming language, after data
  abstraction and inheritance.
 C++ virtual function is a member function of a class, whose functionality can b
  over-ridden in its derived classes.
  C++ virtual function is,
   * A member function of a class
  * Declared with virtual keyword
  * Usually has a different functionality in the derived class
  * A function call is resolved at run-time
  C++ virtual functions are used to achieve run time polymorphism. To declare a
  virtual function virtual keyword is put at the start of normal function declaration
  Requirements for implementing virtual function-
   * Base Class Pointer
   * Inheritance
   * Method Overriding.
   It is a functions whose behavior can be overidden with an inherited class by a
   function of same signature. It is an important part of OOPS and Polymorphism
What is a virtual function ?
 A virtual function is a member function that is declared within the
   base class and redefined by a derived class. When a class
   containing a virtual function is inherited ,the derived class redefines
   the virtual function to fit its needs.
 A virtual function is a member function you may redefine for other
   derived classes, and can ensure that the compiler will call the
   redefined virtual function for an object of the corresponding derived
   class, even if you call that function with a pointer or reference to a
   base class of the object.
 You declare a function with the keyword virtual if you want the
   compiler to use dynamic binding for that specific function.
 A class that declares or inherits a virtual function is called a
   polymorphic class
 A virtual function must be one of the following:
1) Defined
2) Declared pure
Pure virtual functions and abstract classes

 A pure virtual function is a virtual function that has no
  defination within the base class and it acts as a
  placeholder that is meant to be redefined by each
  derived class. When we add a pure virtual function to a
  class we actually mean to say that “ it is up to the
  derived class to implement this function “
 Pure virtual functions are also called “do-nothing “
  functions in C++ because these functions are defined
  with a “null” body (they have no defination)
 The syntax is :
virtual return-type function-name(parameter list)=0;
When a virtual function is made pure, any derived class
  must provide its own defination. If the derived class fails
  to override the pure virtual function a compile time error
  will result
Pure virtual functions and abstract classes
 You can recognize a pure virtual function because it uses the virtual
  keyword and is followed by = 0. If anyone tries to make an object of an
  abstract class, the compiler prevents them (error ). This is a tool that
  allows you to enforce a particular design.
 A class that contains at least one pure virtual function is said to be
  abstract class. Because an abstract class contains one or more
  functions for which there is no defination (pure virtual function ) , no
  objects for that class may be created.. Instead , an abstract class
  constitutes an incomplete type that is used as a foundation for derived
 Abstract classes act as expressions of general concepts from which
  more specific classes can be derived. You cannot create an object of an
  abstract class type; however, you can use pointers and references to
  abstract class types.
 A class that contains at least one pure virtual function is considered an
  abstract class. Classes derived from the abstract class must implement
  the pure virtual function or they, too, are abstract classes.
 Creating a pure virtual function allows you to put a member function in
  an interface without being forced to provide a possibly meaningless
  body of code for that member function. At the same time, a pure virtual
  function forces inherited classes to provide a definition for it.
Pure virtual functions and abstract classes
  class person
    {    virtual void print () = 0;      };
 In the above example print() is a “dummy” function ,that means now person
  is an abstract class and cannot be instantiated (u cannot create an object of
  person class) The intention of person class is to provide a common
  interface for all the classes derived from it. The only reason to establish the
  common interface is so it can be expressed differently for each different
  subtype. It creates a basic form that determines what’s in common with all
  of the derived classes – nothing else.

                               Virtual void print()

           Secretary                     Teacher             Student
                                                           Void enter()
          void print()                Int calculate()       void print()
                                        void print()
     Destructors and Virtual Destructors
 The constructor has the special job of putting an object together piece-
  by-piece, first by calling the base constructor, then the more derived
  constructors in order of inheritance (it must also call member-object
  constructors along the way). Similarly, the destructor has a special job:
  it must disassemble an object that may belong to a hierarchy of
  classes. To do this, the compiler generates code that calls all the
  destructors, but in the reverse order that they are called by the
  constructor. That is, the destructor starts at the most-derived class and
  works its way to the base class destructor . The proper hierarchy of
  constructor and destructor calls is automatically generated by the
 When an object is created with instantiating the derived class like
  [baseclass* bclass =new derivedclass() ] when you delete the base
  class pointer it calls the derived class destructor also so it leaves no
  chance for memory leak. If we do not declare the base class
  destructor as virtual ,only the base class destructor would be
  called when we say (delete bclass)
Virtual Base class

Consider a situation where 3 kinds of
 inheritance are involved: multilevel,
 hierarchical and multilevel


   internalexams             externalmarks

Virtual Base class
 In this case the marks class has 2 direct base classes namely internalexams
    and externalexams ,which themselves have a common base class :student.
    The class marks inherits the traits of student class via two separate paths: first
    from internalmarks and second from externalmarks . Student is called the
    indirect base class. This means that marks class will have duplicate sets of
    the members inherited from “student “ class . This introduces ambiguity and
    must be avoided . The duplication of inherited members due to these multiple
    paths can be avoided by making the common base class as virtual class .i.e:
class student
class internalmarks: public virtual student
class externalmarks: virtual public student
Class marks: public internalmarks, public exernalmarks
{//only one copy of student will be inherited
Virtual Destructor
 The problem occurs when you want to delete a
  pointer of this type for an object that has been
  created on the heap with new. If the pointer is to
  the base class, the compiler can only know to
  call the base-class version of the destructor
  during delete. Forgetting to make a destructor
  virtual in a base class is a bug because it often
  doesn’t directly affect the behavior of your
  program, but it can quietly introduce a memory
  leak. Without a virtual destructor the proper
  destructor may not be
Why are there no virtual constructors?
 Declaring something virtual in C++ means that it can be
  overridden by a sub-class of the current class, however the
  constructor is called when the object is created, at that time
  you can not be creating a sub-class of the class you must be
  creating the class so there would never be any need to
  declare a constructor virtual
 Basically the virtual table will be constructed inside the
  constructor at the compilation time, this is table will contain
  the information about the all virtual functions present in side
  the class. A virtual table is nothing but an array of pointers to
  the virtual functions. The entries in the virtual table are
  changed at run time to point to the correct function. A
  constructor can not be virtual because at the time when
  constructor is invoked the virtual table would not be available
  in the memory .hence we can not have virtual constructor,
  (this is first time when we are invoking the constructor), Vtable
  is unique for the class
Why are there no virtual constructors?
 The reason is that a virtual function is a function whose
  behavior depends on the type of the object that it's called for.
  A virtual call is a mechanism to get work done given partial
  information. In particular, "virtual" allows us to call a function
  knowing only an interfaces and not the exact type of the
  object. To create an object you need complete information. In
  particular, you need to know the exact type of what you want
  to create. Consequently, a "call to a constructor" cannot be
 A virtual function is a function whose behavior depends on the
  type of the object that it's called for. Because constructors
  don't act on objects, but instead create them, a virtual
  constructor is not needed. A virtual call is a mechanism to get
  work done given partial information. In particular, "virtual"
  allows us to call a function knowing only an interfaces and not
  the exact type of the object. To create an object you need
  complete information. In particular, you need to know the
  exact type of what you want to create.
    What is composition?
 You simply create objects of your existing class inside the new class.
   This is called composition because the new class is composed of
   objects of existing classes.
 Composition allows software to be developed by assembling existing
   components rather than creating new ones. Composition defines the
   process of putting an object of one class inside another class as data
   member . It models the “has-a” relationship.. Composition is the
   relationship between a class and its constituent parts. Example of “has
   –a” kind of relationship:
 A university has an affiliated college
We have 2 classes –university and affiliated college , making use of the
   object of affiliated college inside university class is going to model
An automobile has an engine
A human being has a heart
Composition vs. Inheritance
 Inheritance and composition are the two most common
  mechanisms for software reuse. However, there exist
  some differences between the two
 Inheritance is used to model “Is a kind of “ relationship
  whereas composition is used to model “has a kind of “
 A human being “has a” heart , we cannot say that a
  human being “is a” heart
 Inheritance:- Two class can exhibits an IS_A relationship
  Composition:- This concept comes under containment
  (in which one (outer) object holds another (Inner) object).
  This shows the HAS_A relationship. In this type of
  containment the outer object controls the life time of the
  inner objects. e.g (outer)[Bank] HAS_A [Account](inner).
   Aggregation vs. Composition
 Composition and Aggregation are basically whole/part
 Composition: When the lifetime of the part is dependent on or
  controlled by the whole, the relationship between the whole and
  part is Composition. Which simply means that the part is no more
  existing when the whole is destroyed.
 example : car and engine.
  Aggregation :
  When the lifetime of the part is not dependent on or not controlled
  by the whole, the relationship between the whole and part is
  Aggregation. which simply means that the part continues to exist
  when the whole is destroyed.
example : car and stereo
 The only difference between composition and aggregation is
  lifetime. With composition, if object “a” is associated with objects
  b and c, and object a is destroyed, objects b and c are destroyed
  too. With aggregation b and c could live if a was destroyed.
Aggregation vs. Composition
 Aggregation differs from ordinary composition in that it does not
  imply ownership. In composition, when the owning object is
  destroyed, so are the contained objects. In aggregation, this is not
  necessarily true. For example, a university owns affiliated colleges,
  and each affiliated college has a number of professors. If the
  university closes, the affiliated colleges will no longer exist, but the
  professors will continue to exist. Therefore, a University can be seen
  as a composition of affiliated colleges, whereas affiliated colleges
  have an aggregation of professors.
 Aggregation - Without whole ,part can exist.
  Composition - Without whole, part can't exist
 Aggregation or Composition depends up on life time of the
  child object.
  If the child object cannot exist beyond the lifetime of its parent
  then the relationship is composite (Strong relationship)
  If the child object can exist beyond the lifetime of its parent,
  then the relationship is aggregation
What is Delegation?
 Delegation Is a way to make composition as
  powerful as inheritance . There are 2 objects
  involved , one receiving object delegates
  operations to its delegate
 Delegation is an alternative approach, that is we
  can delegate some of the behavior of our new
  class to an object of the existing class without
  inheriting from it. (refer to example given in ch
  14 of venugopal)
What is Run Time Type Identification (RTTI)
   In polymorphic languages like C++ , there can be situations in which
     the type of the object is unknown at compile time,because the
     precise nature of that object is not known till the program is
     executed. Since the base class pointer may be used to point to the
     objects of base class or the objects of derived classes, it is not
     always possible to know in advance what type of object will be
     pointed to by the base class pointer at a given moment in time. This
     determination can be done at run time using RTTI
   In order to obtain an object’s type use
  here object will be the object whose type u will be obtaining
  u can use dynamic_cast operator also to get information of object at
     run time
dynamic_cast performs a run time cast that verifies the validity of a cast. If the
     cast is invalid at the time when dynamic_cast is executed ,then the cast fails
dynamic_cast<target type>(expr)
Target type is specifies the target type of the cast and expr is expression being
     cast into the new type
Class base
{ public:
   virtual void func();
Class derived: public base
Void main()
   base *pb;
 derived *pd, d1;
If( pd=dynamic_cast<derived *>(pb)
  cout<<“type derived”;

Shared By: