static and dynamic polymorphism in c4876

Upload: jimmy-gupta

Post on 14-Apr-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    1/29

    Polymorphism in C++

    24th Aug 2007

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    2/29

    Overview

    Polymorphism means Many forms

    OO PuristsOnly virtual methods

    Liberal C++ guys Either virtual methods(Behavior), or templates (Types), or even

    function overloading for that matter

    (Behavior)

    Generally accepted virtual method

    based, and template based

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    3/29

    Kinds of Polymorphism

    Runtime/Dynamic polymorphism (Based

    on virtual methods)

    Compile time/Static polymorphism (Based

    on templates)

    These 2 are largely orthogonal techniques,

    but many ways where one could be

    replaced with the otherand thats where

    the confusion

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    4/29

    Any of them works example

    // Using virtual method based polymorphism// lock is a virtual method. SingleThreading and Multi-

    threading are 2 derived classes which define lock()

    differently

    void func(BaseThreadingPolicy * pThreadingPolicy)

    {

    pThreadingPolicy->lock();};

    // Using template based polymorphism

    SingleThreading and Multi-threading both implement a lock()

    method, but the neednt have any virtual methods, nor do

    they need to derive from a common base classtemplate func(T* pThreadingPolicy)

    {

    pThreadingPolicy->lock();

    };

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    5/29

    Any of them works - Contd

    In the previous slide we have shown thattemplates arent restricted topolymorphism of type alone, but they also

    can be used for polymorphism of behavior In fact the template version in the previous

    example yields much faster code than thevirtual method equivalent

    Much prevailing confusion about whichtechnique to use in what situation

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    6/29

    Runtime polymorphism

    Runtime binding between abstract type

    and concrete type

    Enforces a common interface for all

    derived types via the base class

    Enforces an Is-A relationship

    Used extensively in OO frameworks Templates eating into parts of its territory

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    7/29

    Compile time Polymorphism

    Compile time binding between abstract type andconcrete type

    Concrete types need not belong to the same

    inheritance hierarchy. They just need to meetthe Constraints imposed by the generic type.So, more generic than the virtuals

    Foundation of Generic programming or

    programming based on Concepts (Eg: STL) A very Happening area in C++ right now (See

    TR1, Boost, C++0x...)

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    8/29

    Why all the excitement about

    templates?

    Templates

    Buy us generality in software, without the

    Abstraction penalty

    Are type safe

    Are non-intrusive

    Allow both reference and value semantics

    unlike virtuals

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    9/29

    Design of reusable data structures

    Inheritance or Templates?Index Inheritance based

    approachTemplate based approach

    1 Slower (virtuals) Faster

    2 Non type-safe(Crash!)

    Type safe

    3 Intrusive (put an

    int/char inside a classand derive from base)

    Non-Intrusive

    4 Reference semantics

    only (leaks, crashes..)

    Value or Reference

    semantics, both allowed

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    10/29

    Sure choice - Templates

    So, templates lead to Faster, Safer, and

    Easier to reuse data structures than

    inheritance

    Using inheritance for designing generic

    data structures, is a common mistake in

    C++

    Dates back to days where compiler

    support was bad for templates

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    11/29

    Why inheritance then?

    Code and structure reuse from baseclasses

    OO Frameworks

    Framework implementation requiresHeterogeneous containers

    Reactor example

    Often depend on polymorphic return types Factory example

    Cant do that with templates

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    12/29

    Choosing your polymorphism

    Dont overuse inheritance (Implementingdata structures using inheritance is anexample of misuse of inheritance)

    Evaluate if your design could be doneusing templates, they are faster and saferthan virtuals.

    Read up on templates and be aware of itspitfalls (Another class of mine will deal withthat)

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    13/29

    Vanilla or Strawberry? I think Ill

    have both

    Templates and Inheritance can be combinedsometimes Eg 1: Singleton pattern implementation

    Eg 2: Reusable object counter

    Eg 3: Reducing template code bloat

    Weakness of inheritanceBase classes dontknow the type of their derived classes

    Static attributes in base class are Shared Weakness of templatesThey dont lead to an

    Is-A relationship

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    14/29

    Singleton using the van-berry flavor

    Best of both worlds

    Have base class know the derived class type

    by using templates [So, getInstance in the

    base class is able to create a derived classinstance]

    Enforce Is-A relationship using inheritance

    [Eg: Make ctor private in the base class, sonobody can instantiate a derived class

    instance as well]

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    15/29

    Object counter

    Synergy again

    Base classes need to share the staticattributes

    Use templates to get over that issue Onebase class generated for each derived class

    Use inheritance for the Is-A relationship[Whenever the class ctor is called, the base

    class ctor is called, likewise for the dtor,increment and decrement operations happenautomatically]

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    16/29

    Cost of runtime polymorphism

    Each class that has a virtual method has anassociated vtable

    A vtable is just an array of function pointers

    containing pointers to virtual methodimplementations for that class

    Each object of any such class, has a pointer tothe associated vtable

    The compiler creates the required vtables andinitializes each object to point to the associatedvtable all Under the hood

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    17/29

    Illustration

    Class Base{

    public:

    Base();

    virtual void func1();

    virtual void func2();

    virtual ~Base():};

    Class Derived

    {

    public:

    Derived();virtual void func1();

    virtual ~Derived();

    };

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    18/29

    Illustration (Contd)

    Pointer to Base::func1

    Pointer to Base::func2

    Pointer to Base::~Base

    vtable for the Derived class

    Pointer to Derived::func1

    Pointer to Base::func2

    Pointer to Derived::~Derived

    vtable for the Base class

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    19/29

    Illustration (Contd)

    Base Object

    Base Object

    Base Object

    Derived Object

    Derived Object

    Derived Object

    Base class vtable

    Derived class vtable

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    20/29

    What happens at runtime?

    The compiler would have converted allyour virtual method calls

    Your call: pDerived->func2();

    Its become: (*pDerived->vptr[1])(pDerived) As we see above, the vptr stored by the

    compiler in the derived object is looked up,

    an offset (+1) added to get to the secondvirtual method in the class, and thefunction is called

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    21/29

    So, whats the cost?

    Direct cost vtable lookup (Put at about 5-10% overhead as opposed to non-virtualmethods)

    Indirect cost Cannot inline virtual methods (Makes a big

    difference)

    Each objects needs to store extra pointer (Anissue for fine grained objects say 1000000link element objects, each containing 4 bytesextra!)

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    22/29

    Is that all?

    Well, this gets worse when MI (Multiple

    Inheritance is used)

    Now, the deal is 15-20% overhead for MI for

    method defined in the 2nd and onwards baseclass. Theres no penalty for methods in the first

    base class we derive from

    Ensure your most frequently called methods are

    from the FIRST base class you derive from if

    you use MI, order your base classes accordingly

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    23/29

    Cost of compile time polymorphism

    ZERO runtime cost (Abstraction without

    abstraction penalty)

    However

    Coders not aware of how templates work

    Under the hood end up creating code bloat

    Developer turn around time increased due to

    longer compiles (This could be avoided too)

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    24/29

    Template code bloat

    Code bloat happens because compilers cannotdo Commonality and variability analysis

    If the code body is the same for a set of template

    argument values, the compiler fails to see thatand generates multiple classes for eachargument value

    Eg: list, list

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    25/29

    Template code bloat (Contd)

    A coder who knows this, does thefollowing

    Give a partial template specialization for

    POINTER types Have that derive from a void * based

    container which has most of theimplementation in it

    This specialized class will have simple inlinemethods that Delegate to the base class andgets work done

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    26/29

    Template code bloat (Contd)

    So, we get the following result

    The thin inline wrappers in the specialized

    class offer type safety

    Majority of the code body is in the non-template base class and hence no duplication

    of it

    The thin wrappers are all inline hence noperformance overhead as well

    This is called the Hoisting idiom

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    27/29

    Longer compilation time

    Happens mainly because the template

    method definitions have to be in the

    header file

    They may in turn pull in other headers and

    hence lead to large include sizes and

    hence more compile time

    More work to the compiler in case one

    uses template meta-programming

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    28/29

    Workaround

    To reduce compile times, we can use theExplicit instantiation technique in caseswhere large includes are warranted

    Here basically you give the method bodyin a .cpp file and put only the templateclass definition in the .h file, but explicitlyinstantiate the template in the .cpp filewhere the methods are defined for alltypes expected

  • 7/30/2019 Static and Dynamic Polymorphism in c4876

    29/29

    Summary

    Prefer inheritance when

    You want to reuse code/structure from thebase class

    You want to develop OO frameworks whichneed to store heterogeneous elements in theirdata structures

    Prefer templates when

    You want generic data structures andalgorithms

    Where Speed is important