static and dynamic polymorphism in c4876
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