Presentation is loading. Please wait.

Presentation is loading. Please wait.

Interra Induction Training

Similar presentations


Presentation on theme: "Interra Induction Training"— Presentation transcript:

1 Interra Induction Training
Programming in C++ Kolkata, July 11, 2006 Camp 06 Maturing Minds

2 Object Oriented Programming in C++ Inheritance

3 Topics to be discussed Fundamentals of Inheritance
protected Access Specifier Initialization Virtual Functions CAMP 06: Maturing Minds

4 Reusability Reuse an already tried and tested code Advantages:
Reduces cost & development time. Improves quality C Style Code Reuse Library Function Disadvantage: Reuse cannot be customized C++ Style Reuse: Inheritance Composition CAMP 06: Maturing Minds

5 Basics of C++ Inheritance
If a class A is derived from another class B then A is called the derived/sub class and B is called the base/super class. All (?) data members and methods of the base class are immediately available to the derived class. Thus, the derived class gets the behavior of the base class The derived class may extend the state and behavior of the base class by adding more attributes and methods. CAMP 06: Maturing Minds

6 Accessibility of Base Class Members
What happens to the access specifier of the members of the base class when they are derived? Depends on the mode of derivation. In public inheritance, private members of the base class become private members of the derived class and public members of the base class become public members of the derived class However, private members of the base class are not directly accessible to the members in the derived class. CAMP 06: Maturing Minds

7 Object Layout in Inheritance
Assume the following class hierarchy class C: public B { .. }; class B: public A class A Layout for an object of type C A - Part Data Member B-Part Data Member C-Part Data Member CAMP 06: Maturing Minds

8 protected Members private data members of the base class cannot be directly accessed by the methods of the derived class. However, it is important for the derived class to have more accessibility to the members of the base class than other classes or functions. If a member is protected then it is directly accessible to the methods of the derived class. CAMP 06: Maturing Minds

9 Syntax of Inheritance An example class Employee { protected:
float basic; long id; public: Employee(long id); float getSalary(); }; class Manager : public Employee Employee *supervised[10]; int numberOfPeopleManaged; Manager(Id, n); void printSupervisedEmployeeId(); } CAMP 06: Maturing Minds

10 Order of Constructor Calls
The constructor of the derived class is responsible for initializing the state of the derived object. The derived object contains attributes which are inherited by the derived class. The constructor of the derived class calls an appropriate constructor of the base class Therefore, the constructor of the base class is executed first and then the constructor of the derived class is executed. CAMP 06: Maturing Minds

11 Example of Derived Class Constructor
Employee::Employee(long id) { this->id = id; } Manager::Manager(long id, int n) : Employee(id) numberOfPeopleManaged = n; CAMP 06: Maturing Minds

12 Order of Destructor Calls
The destructor of the derived class is responsible for cleaning up the state of the derived object. The derived object contains attributes which are inherited by the derived class. The destructor of the derived class calls the destructor of the base class Therefore, the destructor of the base class is executed first and then the destructor of the derived class is executed. CAMP 06: Maturing Minds

13 Casting Derived class pointer can be implicitly cast to a base class pointer Manager m; Employee *e = &m; // Employee *e = (Employee *)(&m); Only base class part of the derived object can be seen through the base pointer. e-> printSupervisedEmployeeId(); //error A Base class pointer cannot be implicitly cast to a derived class pointer Manager *pM; pM = e; //error pM = (Manager *)e; //ok Down casting may be dangerous CAMP 06: Maturing Minds

14 Static vs. Dynamic Binding
Binding refers to associate a type to a name. Consider the following example: Manager m; Employee *e = &m; e->getSalary(); //Which getSalary? Employee or Manager? “e” is declared as a pointer to Employee In the example however, it makes more sense to mean “getSalary” of the Manager class. We need a dynamic binding of “e” so that the type of “e” may be set at run time by pointer to the type of the actual object This is also called late binding CAMP 06: Maturing Minds

15 Virtual Functions In C++, dynamic binding is made possible only for pointer & reference data types and for methods that are declared as virtual in the base class. If a method is declared as virtual, it can be overridden in the derived class. If a method is not virtual and it is re-defined in the derived class then the latter definition hides the former one. CAMP 06: Maturing Minds

16 Virtual Function: Example
class X{ class Y: public X{ public: public: int f(){ return 2; } int f(){ return 4;} virtual int g(){ return 3;} int g(){ return 6;} }; }; main() { Y a; int i, j , k, m; X *b; b = &a; i = b->f(); j = a.f(); k = b->g(); m = a.g(); printf(“%d %d %d %d\n”, i, j, k, m); } Output will be CAMP 06: Maturing Minds

17 Redefining a Non-Virtual Function
Simply do not do that. class X() class Y : public X { { protected: protected: void f(); void f(); }; }; int main() { Y y1; Y *pY; X *pX; pX = &y1; pX->f(); // f as defined in X will be called pY = &y1; pY->f(); // f as defined in Y will be called } CAMP 06: Maturing Minds

18 Virtual Function Table
If a class has a virtual function, then each instance of that class contains a space to store a pointer to the actual definition of that function. During creation, the actual address of the function is assigned to the function pointer. Y is derived from X, which has a virtual function. X-part-data X-part-virtual-function-ptr Y-part-data Actual definition of the virtual function CAMP 06: Maturing Minds

19 Abstract Class Pure Virtual Function
A virtual function may be assigned to NULL meaning that this function is declared but not defined in a class. Definition of such a class is incomplete. A class with one or more pure virtual function is called an abstract class. Abstract class cannot be instantiated. Abstract class define a contract or interface to be used by the user of the class library and to be implemented by the developer of the class library. CAMP 06: Maturing Minds

20 Virtual Destructor Constructors cannot be virtual
For a base class which has been derived from, the destructor must be declared virtual. Occasionally we create a derived object and store it using a pointer to Base class such as Base *pBase = new Derived(/*arguments*/); If we destroy this object using “delete pBase” then two destructors need to be called. If the destructor in the Base class is not declared virtual then the destructor of the Derived class will not be automatically called in this example. CAMP 06: Maturing Minds

21 Inheritance Example: Polymorphic Array
Consider an abstract base class Shape which contains a pure virtual function “CalculateArea”. Suppose three classes Triangle, Rectangle and Circle derived from Shape. Consider a main function that creates different Shape objects and store them in an array. If in a for loop the function calculateArea is called on all objects in the array, we see dynamic binding in use. CAMP 06: Maturing Minds

22 Polymorphic Array: Class Definitions
class Shape { public: virtual double calculateArea() = 0; }; class triangle : public Shape() private: Point a, b, c; Triangle(double x_a, double y_a, double x_b, double y_b, double x_c, double y_c); double calculateArea(); class Circle : public Shape() { private: Point centre; double radius; Circle(double x_centre, double y_centre, double r);, public: double calculateArea(); }; CAMP 06: Maturing Minds

23 Polymorphic Array: main function
int getInput(Shape *pArr) { int i, double x_a, x_b, x_c, y_a, y_b, y_c; scanf(“%d”, &i); while (1) switch (i) case 0: break; case 1: scanf(“%f%f%f%f%f%f”, &x_a, &y_a, &x_b, &y_b, &x_c, &y_c); pArr[I] = new Triangle(&x_a, i++; break; …….. } int main() { Shape *pArr = NULL; int n = 0; n = getInput(pArr); int i; for (i = 0; i < n; i++) double area = Shape[i]->calculateArea(); printf (“%lf \n”, area); } int getInput(Shape *pArr) printf(“Which Shape do you want to create?\n”); printf(“Write 1 for triangle, 2 for rectangle, 3 for circle and 0 to quit\n”); CAMP 06: Maturing Minds

24 Inheritance: Benefits
Code Sharing/Reuse Consistency of Interface Construction of Software Components Rapid Prototyping Information Hiding CAMP 06: Maturing Minds

25 Inheritance: Cost Execution Speed Program Size
Message Passing Overhead Program Complexity CAMP 06: Maturing Minds

26 Inheritance: Limitations
operator= cannot be inherited Can be used to assign objects of the same type only Copy Constructor cannot be inherited Static members are inherited in a derived class Static members cannot be “virtual” If you redefine a static member function, all other overloaded functions in the base class are hidden CAMP 06: Maturing Minds

27 Interra Induction Training
Object Oriented Programming in C++ More on Inheritance Kolkata, July 22, 2005

28 Inheritance Notes Constructors cannot be virtual
Calling a virtual function from within a constructor does not have the desired effect. The following code is buggy. Tell why. void f(Base *b) int main() { { b[0].f(); b[1].f(); Derived d[10]; } f(d); } Derived is publicly derived from Base. Class Base has a virtual function “f” which is redefined in Derived. CAMP 06: Maturing Minds

29 Default Parameter & Virtual Function
You should not change the default parameter in a redefined virtual function class X() class Y : public X { { protected: protected: virtual void f(int i = 10); virtual void f(int i =20); }; }; int main() { Y y1; Y *pY; X *pX; pX = &y1; pX->f(); // f with value of i as 10 will be called pY = &y1; pY->f(); // f with value of i as 20 will be called } CAMP 06: Maturing Minds

30 Is an Ostrich a Bird Suppose there is a base class Bird
a virtual method fly returns altitude > 0. A class Ostrich is derived from Bird. fly method has to be redefined as an empty function. Leads to a logical dilemma. Can an overridden method be empty? Can an overridden method throw exceptions? CAMP 06: Maturing Minds

31 Is a Circle an Ellipse? Circle is a special type of ellipse.
Let Circle be derived from Ellipse. Suppose that Ellipse has a method setSize(x,y). Also suppose that there is a function sample as defined below. sample (Ellipse &e) { e. setSize(10,20); ……. } If sample is called on a circle, strange things happen! Subset is not substitutable!! CAMP 06: Maturing Minds

32 Should a Stack inherit from a List?
Probably Not! If List is the base class of Stack Methods such as push, pop etc. are to be defined (at least as pure virtual) in the List class. All members of List must have (even a trivial) implementation in Stack. A Stack has a List. CAMP 06: Maturing Minds

33 Multi-level Inheritance
Suppose that C is derived from B and B is derived from A. Suppose that a method, f, in A is virtual. If f is redefined in B then f is virtual even if the keyword “virtual” does not precede the declaration/definition in the derived class. It is advisable to explicitly write “virtual” in front of the definition of f in B as, otherwise, an implementer of C may think that f is not a virtual method. CAMP 06: Maturing Minds

34 Inheritance & Code Reuse
Suppose that C and B and are derived from A. Both C and B contain a function f ; therefore, f is made a virtual (not pure) function in A. This is bad. A new class D is required to be derived from A later. f in D is different than A. Interfaces should not have implementation. CAMP 06: Maturing Minds

35 private Inheritance If B is privately derived from A then private, protected and public members of A become private members of B. However, private members of A are not directly accessible to B. Thus, even if C is publicly derived from B then no member of A is accessible to C. Functions which may access members of A in B are Methods of class B Friend functions of class B. CAMP 06: Maturing Minds

36 protected Inheritance
If B is protectedly derived from A then, protected and public members of A become protected members of B. However, private members of A remain private in B and are not directly accessible to B. Functions which may access members of A in B are Methods of class B Friend functions of class B. Methods in classes publicly derived from B Friend functions of classes publicly derived from B CAMP 06: Maturing Minds

37 Private Inheritance: Implications
public Inheritance models “is a” private inheritance models “is implemented in terms of ” Assume two classes, Set and List. Set contains unique elements while List may contain duplicate elements. Thus Set is not a List But a Set can use the code of the List class as a Set can be implemented in terms of a list. Users of the class Set should not have an access to the List behavior even to create further derived classes CAMP 06: Maturing Minds

38 Interra Induction Training
Object Oriented Programming in C++ Exceptions Kolkata, July 22, 2005

39 Topics Basic Concept of Exceptions try-catch block in C++
Semantics of throw CAMP 06: Maturing Minds

40 Error Handling in C++ Error Condition Handling - C Style
via return value return statement is dedicated for passing error conditions by output parameter normal and abnormal control flow tend to mix Reusing code for error handling is difficult. Error Condition Handling - C++ Style On error condition an exception object is created and thrown. A function catches exception objects generated from the function it calls in a distinct control flow. Similar Exception objects can enjoy benefits of inheritance. CAMP 06: Maturing Minds

41 C-Style Error Handling
int Calculator::divide (int i) { if (i == 0) // what do we do? } else value /= i; return value; A Calculator need to handle divide by zero Could set value to NAN But, program would need to check for special value (and might ignore) Could return –1 Again program could ignore Might be a valid return value CAMP 06: Maturing Minds

42 “try” and “catch” A function has its usual prototype and it may throw a number of exceptions on detecting several error condition. “try” block encloses code that has usual flow of control and can potentially throw exceptions “catch” block can occur after a “try” block or another “catch” block catch blocks can catch and handle exceptions of different types CAMP 06: Maturing Minds

43 Exception Object and throw
Exception object is just another object having members (attributes and methods) suitable to model the state and behavior of an object representing an error condition. Whenever an error condition is detected, a suitable Exception object is thrown.Semantics of throw is as follows. Creation of an object (function of new) passing control from this function to the caller function (similar to return) Unlike return, throw initiates unwinding of the call stack till the exception is handled. CAMP 06: Maturing Minds

44 Example of Exception Handling in C++
class DivideByZero{ private: int dividend; public: print() { cout << dividend << “is divided by zero” <<endl; } DivideByZero(int d) { dividend = d; } }; int Calculator::divide(int i) throws DivideByZero { if (I ==0) throw DivideByZero(value); value /= I; return value; int main (int argc, char **argv) { int i = 0; Calculator c; try c.divide (0); cout << c.getValue (); } catch (DivideByZero ext) ex.print(); return 1; return 0; CAMP 06: Maturing Minds

45 Details of throw Normal program control flow is halted
At the point where an exception is thrown The program call stack “unwinds” Stack frame for each function up call chain is popped Stack variables in each popped frame are destroyed Until an enclosing try/catch scope is reached where the type of exception thrown is caught. Control passes to first matching catch block Can handle the exception and continue Can free resources and re-throw CAMP 06: Maturing Minds

46 More on “try” and “catch”
Whenever a function is called in a try block, the “catch” blocks to be examined after the try block are known as the extended prototype of a function includes the throw clauses. catch blocks after a try block are examined in order when an exception is thrown from a function called in the try block. Parentheses for each catch block has semantics of a “function argument declaration” CAMP 06: Maturing Minds

47 Exception Specifications
Make promises to the caller Allow stronger type checking enforced by the compiler By default, a function can throw anything it wants A throw clause in the signature Limits what a function can throw A promise to the calling function A throw clause with no types Promises nothing will be thrown Can list multiple types Comma separated // can throw anything void Calculator::subtract (int i); // promises not to throw Calculator::add (int i) throw (); // promises to only throw int Calculator::divide (int i) throw (int); CAMP 06: Maturing Minds

48 previous frame pointer
Stack Frame g++ -s gives assembler output that can be used to deduce exact structure for a given platform In general, the overall structure is common A chunk of memory representing a function call Pushed on program call stack at run-time Contains: The frame pointer The return address for the call (i.e., where it was called from) Parameters passed to the function Automatic (stack) variables for the function automatic variables parameters previous frame pointer return address CAMP 06: Maturing Minds

49 Illustrating the Call Stack
Stack frame for function main Pushed on program call stack With stack variables i and c With parameters argc and argv Note that parameters are initialized at frame creation Variables are not necessarily initialized at frame creation May occur later in called function int main (int argc, char **argv) { int i = 0; Calculator c; try c.divide (0); cout << c.get_value (); } catch (int) return 1; return 0; i c value_ main argc argv CAMP 06: Maturing Minds

50 Illustrating the Call Stack, cont.
int main (int argc, char **argv) { int i = 0; Calculator c; try c.divide (0); cout << c.get_value (); } catch (int) return 1; return 0; Enter function main Stack variable initialized to 0 i c value_ main argc argv CAMP 06: Maturing Minds

51 Illustrating the Call Stack, cont.
int main (int argc, char **argv) { int i = 0; Calculator c; try c.divide (0); cout << c.get_value (); } catch (int) return 1; return 0; Call Default Constructor for c Push a new stack frame No parameters or automatic variables for that specific function Params depend on function signature declaration Automatics depend on function body definition Calculator:: Calculator ( ) this i c value_ main argc argv CAMP 06: Maturing Minds

52 Illustrating the Call Stack, cont.
Calculator::Calculator () : value_ (0) {} void Calculator::divide (int i) throw (int) { if (i == 0) { throw i; } else { value_ /= i; } cout << value_; Enter function Calculator::Calculator ( ) Member variable value_ of stack variable c is initialized to zero How do we know which value_ to set? There may be multiple Calculator instances Answer: implicit “this” parameter in stack frame Calculator:: Calculator ( ) this i c value_ main argc argv CAMP 06: Maturing Minds

53 Illustrating the Call Stack, cont.
Calculator::Calculator () : value_ (0) { } void Calculator::divide (int i) throw (int) if (i == 0) { throw i; } else { value_ /= i; cout << value_; Return from function Calculator::Calculator ( ) Pop the stack frame, return to previous argc argv i c value_ main CAMP 06: Maturing Minds

54 Illustrating the Call Stack, cont.
int main (int argc, char **argv) { int i = 0; Calculator c; try c.divide (0); cout << c.get_value (); } catch (int) return 1; return 0; Call divide method on c Push a new stack frame Contains parameters this and i Copy address of current instance into this Copy value 0 into i void Calculator:: divide (int ) main argc argv i c value_ this CAMP 06: Maturing Minds

55 Illustrating the Call Stack, cont.
Calculator::Calculator () : value_ (0) { } void Calculator::divide (int i) throw (int) if (i == 0) { throw i; } else { value_ /= i; cout << value_; Enter function Calculator::divide (int) Test i equal to 0 and take the true branch Throw integer i main void Calculator:: Calculator (int ) argc argv i c value_ this CAMP 06: Maturing Minds

56 Illustrating the Call Stack, cont.
Calculator::Calculator () : value_ (0) { } void Calculator::divide (int i) throw (int) if (i == 0) { throw i; } else { value_ /= i; cout << value_; Thrown exception unwinds call stack Notice control skips over cout statement to end Pop the stack frame, return to previous Return from function void Calculator::divide ( ) argc argv i c value_ main CAMP 06: Maturing Minds

57 Illustrating the Call Stack, cont.
int main (int argc, char **argv) { int i = 0; Calculator c; try c.divide (0); cout << c.get_value (); } catch (int) return 1; return 0; We’ve reached an enclosing try/catch scope So stack unwinding stops Control jumps to first matching catch block Again, skips over intervening cout statement argc argv i c value_ main CAMP 06: Maturing Minds

58 More on catch Control jumps to first matching catch block
try { // can throw an exception } catch (Derived &d) // ... catch (Base &b) catch (...) // catch all... Control jumps to first matching catch block Order matters with multiple possible matches Especially with inheritance-related exception classes Hint: put catch blocks for derived exception classes before catch blocks for their respective base classes More specific catch before more general catch catch (…) catches any type CAMP 06: Maturing Minds

59 A Few More on catch Notice catch-by-reference for user defined types
try { // can throw an exception } catch (MyClass &e) // ... throw; // rethrows e catch (int) catch (...) // catch all... Notice catch-by-reference for user defined types More efficient Only a reference propagates Rather than entire object More correct Avoids class-slicing problem if catch as base type, rethrow Preserves polymorphism More on this in later lectures Can leave off variable name Unless catch block needs to do something with the instance that was caught CAMP 06: Maturing Minds

60 Interra Induction Training
Object Oriented Programming in C++ Templates Kolkata, July 25, 2005

61 What is a Template? Templates are specifications of a collection of functions or classes which are parameterized by types. Examples: Function search, min etc.. The basic algorithms in these functions are the same independent of types. But, we need to write different versions of these functions for strong type checking in C++. Classes list, queue etc. The data members and the methods are almost the same for list of numbers, list of objects. We need to define different classes, however. CAMP 06: Maturing Minds

62 Function Template: An Example
void swap(int &i, int &j) { int temp; temp = i; i = j; j = temp; } void swap(String &i, String &j) String temp; template<class X> void swap (X &one, X &other) { X temp; temp = one; one = other; other = temp; } Main() { int I=10, j=20; swap(I, j); String s1(“abc”), s2(“def”); swap(s1, s2); Type parameter Type parameter list Template instantiation CAMP 06: Maturing Minds

63 Parameterized Functions
A function template describes how a function should be built supplies the definition of the function using some arbitrary types, (as place holders), a parameterized definition can be considered the definition for a set of overloaded versions of a function is identified by the keyword template followed by parameter identifiers enclosed between < and > delimiters noting they are class, (i.e. type), parameters CAMP 06: Maturing Minds

64 Template Non-type Parameter
It is an ordinary parameter template <class T, int size> T min (T (&x[size])); When min is called, size is replaced with a constant value known at compile time The actual value for a non-type parameter must be a constant expression. CAMP 06: Maturing Minds

65 typename The key words class and typename have almost the same meaning in a template parameter. typename is also used to tell the compiler that an expression is a type expression. template <class T> f (T x) { T::name * p; // Is this a pointer declaration or multiplication? } typename T::name * p; // Is this a pointer declaration or multiplication? CAMP 06: Maturing Minds

66 Template Argument Deduction
Each item in the template parameter list is a template argument. When a template function is invoked, the values of the template arguments are determined by seeing the types of the function arguments. Template <class T, int size> Type min( T(&x[size])); Int pval[9]; min(pval); //Error!! Three kinds of conversions are allowed. L-value transformation (e.g., Array-to-pointer conversion) Qualification conversion Conversion to a base class instantiation from a class template If the same template parameter are found for more than one function argument, template argument deduction from each function argument must be the same. CAMP 06: Maturing Minds

67 Explicit Template Arguments
It is possible to override template argument deduction mechanism and explicitly specify the template arguments to be used. template <class T> T min(T x, T y); unsigned int ui; min (ui, 1024); //Error!! min<unsigned int>(ui, 1024); // OK Specifying return type generically is often a problem. template <class T, class U> ??? sum(T x, U y); sum(ch, ui) returns U; sum (ui, ch) returns T template < class R, class T, class U> R sum(T x, U y) min<int>(i, ‘a’); CAMP 06: Maturing Minds

68 Template Explicit Specialization
Some times, a template may not be suitable for all types. The following template is not good for char * template <class T> T min(T x, T y) { return (x < y ? x : y); } Define the function explicitly for char * template<> char * min <chr *>(char *x, char *y) { return (strcmp(x, y) < 0 ? x : y); } CAMP 06: Maturing Minds

69 Class Template

70 A List Template Class CAMP 06: Maturing Minds template<class T>
class List { public : List (); virtual ~List (); int put (const T &val); T *unput (); T *get (); int unget (const T &val); T *find(const T &val); int length (); private: struct Node { Node *next_item; T *list_item; } *beg_ptr; *end_ptr; int how_many; }; template<class T> int List<T>:: put (const T &val) { Node *tmp_ptr = new Node; if (tmp_ptr && (tmp_ptr->list_item = new T (val) ) ) { tmp_ptr->next_item = 0; if (end_ptr) end_ptr->next_item = tmp_ptr; else beg_ptr = tmp_ptr; end_ptr = tmp_ptr; how_many++; return 1; } return 0; CAMP 06: Maturing Minds

71 Using a Template Class int main () { register int i, *iptr;
String *sptr; char *somedata [] = {“one”, “two”, “three”, “four”, “five”, “six”, “seven”, “eight”, “nine”, “ten”}; List<int> ii; List<String> is; for (i = 1; i <=10; i++) { ii.put(i); } } cout << “The List<int> contains “ ; cout << ii.length () << “ items\n” ; return 0; } CAMP 06: Maturing Minds

72 Parameterized Class A class template
describes how a class should be built Supplies the class description and the definition of the member functions using some arbitrary type name, (as a place holder). is a parameterized type with parameterized member functions can be considered the definition for an unbounded set of class types is identified by the keyword template followed by parameter identifiers enclosed between < and > delimiters noting they are class, (i.e. type), parameters is often used for “container” classes CAMP 06: Maturing Minds

73 Parameter Requirements
Parameter Types may be of any type, (including user defined types) may be parameterized types, (i.e. templates) MUST support the methods used by the template functions: what are the required constructors ? the required operator functions ? What are the necessary defining operations ? CAMP 06: Maturing Minds

74 Class Template Instantiation
Class Template is instantiated only when it is required. Matrix is a class template Matrix m; //error Matrix *pm; // OK void inverse (Matrix & m); //OK Class template is instantiated before An object is defined with class template instantiation If a pointer or a reference is de-referenced (e.g., a method is invoked) A template definition can refer to a class template or its instances but a n non-template can only refer to template instances. CAMP 06: Maturing Minds

75 Friend & Static Declaration
There are 3 kinds of friend declarations Non-template friend. A bound friend class template. One-to-one mapping between the instance of a class template and its friend An unbound friend class template. One-to-many mapping between the instance of a class template and its friend Operators can be overloaded for a class template A static data member in a class template is itself a template. Each static data member instantiation corresponds to a class template instantiation. CAMP 06: Maturing Minds

76 Source code organization
Inclusion Model Make the template definition visible to compiler at the point of instantiation Include source files as well. Increase in build and link time Instantiate the types you need explicitly in a separate compile unit. Cannot use benefits of lazy instantiation. Separation Model Use keyword ‘export’ in front of definition. Not many compiler supports the feature. CAMP 06: Maturing Minds

77 Template specialization
Allows to make specific implementation when pattern is of determined type. The syntax is template<> class XXX<Type> {..} No member is ‘inherited’ from the generic template to specialized one. So, must define ALL members equating them to specialization Class templates can be partially specialized too. A totally disjoint template that the compiler gives a priority while instantiation. CAMP 06: Maturing Minds

78 Templates & Derivation
A template expresses a commonality across types Two types generated from a common template are different. A Base class expresses commonality of representation and calling interface. Example template <class T, class A> class specalContainer : public Container<T>, A; specialContainer<Node, Fast_Allocator> s; specialContainer<Node, Shared> s1; specialContainer<ProcessDescriptor, Fast_Allocator> p; CAMP 06: Maturing Minds

79 Template Inheritance: A Base Template
template<class T> class set { public : Set ( ) { } ; virtual void add (const T &val); int length ( ) ; int find (const T &val); private: List<T> items; }; template<class T> void Set<T> : : add (const T &val) { if (items.find (val) ) return; items.put (val) ; } int Set<T> : : length ( ) return items.length ( ) ; int Set<T> ::find (const T &val) return (int) items.find(val); CAMP 06: Maturing Minds

80 Template Inheritance: A Derived Template
/* boundset.h */ #include “set.h” template<class T> class BoundSet : public Set<T> public: BoundSet (const T &lower, const T &upper); void add(const T &val); private: T min; T max; }; template<class T> BoundSet<T>:: BoundSet (const T &lower, const T &upper) : min (lower), max (upper) { } void BoundSet<T> : :add(const T &val) if (find (val) ) return; if ( (val <= max) && (val >= min) ) Set<T>: : add (val) ; CAMP 06: Maturing Minds

81 Using a Derived Template Class
int main ( ) { register int i ; BoundSet<int> bsi (3, 21); Set<int> *Setptr = &bsi; for (i = 0; i < 25; i++) setptr->add( i ) ; if (bsi.find (4) cout << “We found an expected value\n”; if (bsi.find (0) || bsi.find(25 ) ) { cout << “We found an Unexpected value\n”; return 23; } else cout << “We found NO unexpected value\n”; return 0; CAMP 06: Maturing Minds

82 Inheritance vs Templates
Inheritance : helps in reusing object code Templates : helps in reusing source-code object code size of template code is therefore much less. Compiler view Constructor of objects containing virtual functions must initialize the vptr table. Template class knows the type of the class at compile-time instead of having to determine it at run-time (as in case of virtual function usage) CAMP 06: Maturing Minds

83 Inheritance vs Templates: Example
Implement the following command. # ECHO infile outfile main() { (argc > 2 ? ofstream (argv[2] ,ios::out) : cout) << (argc > 1 ? ifstream (argv[1], ios::in) : cin) .rdbuf(); } main() { fstream in, out; if (argc > 1) in.open(argv[1], ios::in); if (argc > 2) out.open(argv[2], ios::out); Process(in.is_open() ? in : cin, out.is_open() ? out : cout); } How to implement ‘Process’ ? Two ways to get the polymorphic behavior virtual function and templates CAMP 06: Maturing Minds

84 Inheritance vs Templates: Solution
template<typename In, typename out> void process(In& in, Out& out) { // out << in.rdbuf(); } Merely requires that the passed objects to have suitable interface (such as member function named rdbuf(). ) void Process (basic_istream& in, basic_ostream& out) { // out << in.rdbuf(); } Requirement: cin and ifstream both derived from basic_istream The common base class ‘basic_istream has suitable interface ‘rdbuf’. Both Methods solve the current problem. But templates provide extensibility. Other streams can be provided with rdbuf() interface. Other streams cannot be guaranteed to be derived from the same base class CAMP 06: Maturing Minds

85 Another Example A collection of classes is required for
Stack: for ints , strings, floats etc. Has operations: push, pop, length of stack. transportationMode . For airplane, car, boat etc. Has features : move, comfort etc each move in diff ways. Each provide different level of comfort. Analyze if the ‘type’ being manipulated has any affect on the behavior of class . If ‘type’ does not affect the behavior, use templates If ‘type’ affects the behavior, use virtual functions (inheritance) CAMP 06: Maturing Minds


Download ppt "Interra Induction Training"

Similar presentations


Ads by Google