Download presentation
Presentation is loading. Please wait.
Published byHerbert Cummings Modified over 8 years ago
1
17-1 Computing Fundamentals with C++ Object-Oriented Programming and Design, 2nd Edition Rick Mercer Franklin, Beedle & Associates, 1999 ISBN 1-887902-36-8 Presentation Copyright 1999, Franklin, Beedle & Associates Students who purchase and instructors who adopt Computing Fundamentals with C++, Object-Oriented Programming and Design by Rick Mercer are welcome to use this presentation as long as this copyright notice remains intact.
2
17-2 Chapter 17 Templates Building Generic Classes Chapter Objectives Implement a function that can search and sort vectors of any class Pass class names to container classes just like the C++ standard: bag myBookBag; // bag of book objects bag myBookBag; // bag of book objects bag myCDs; // bag of CD objects bag myCDs; // bag of CD objects Implement generic container classes that store collections of any class of elements
3
17-3 17.1 Templates Consider collection classes store a collection of objects provide suitable access to all elements perhaps with the iterator pattern so far have only stored one class of object Instead of a bag or list of strings how about a bag or list of anything? let's investigate how vectors store a collection of any type of object
4
17-4 bag of this, bag of that The bag class in Chapter 11 requires typedefs to inform bag which class of objects it will store not ideal but better than having a separate collecton class for strings, bankAccounts, grids, weeklyEmployees, and any other new object.... there is a better way This chapter describes templates -- a mechanism that allows the type of object to be stored to be passed as an "argument" betweeen This chapter describes templates -- a mechanism that allows the type of object to be stored to be passed as an "argument" betweeen
5
17-5 17.1.1 Function Templates Let's start with the simpler function template Problem: write a lesser function that returns the "lesser" of any two objects but < is defined for the class examples: int, double, string, or any other type you want to have meaning for less than (bankAccount e.g.) We could write one function for each class/type or we could use function templates
6
17-6 Two options Option 1) One function per class very specific int lesser( int a, int b); int lesser( int a, int b); double lesser(double a, double b); double lesser(double a, double b); string lesser(string a, string b); string lesser(string a, string b); char* lesser( char* a, char* b); char* lesser( char* a, char* b); // And on and on and on... // And on and on and on... Option 2) One function for any class very general use a function template
7
17-7 Function Templates General form and example function heading template that could take any type of class argument and return that class of argument template template function-definition template template // Now use TheClass anywhere in the function // Now use TheClass anywhere in the function TheClass lesser(TheClass a, TheClass b) TheClass lesser(TheClass a, TheClass b) { //... { //... }
8
17-8 Using template parameters Return the "lesser" of any 2 arguments TheClass must define < (See Ch 18: Operator Overloading int, double, string, char already do template template TheClass lesser(TheClass a, TheClass b) TheClass lesser(TheClass a, TheClass b) { // pre: TheClass must define < { // pre: TheClass must define < // post: Return the lesser of the two arguments // post: Return the lesser of the two arguments TheClass result; TheClass result; if(a < b) if(a < b) result = a; result = a; else else result = b; result = b; return result; return result; }
9
17-9 Active Learning What is the Output? int main() int main() { // Test drive a function template { // Test drive a function template cout << lesser(-16, 16) << endl; cout << lesser(-16, 16) << endl; cout << lesser(0.0003, 0.003) << endl; cout << lesser(0.0003, 0.003) << endl; cout << lesser('B', 'b') << endl; cout << lesser('B', 'b') << endl; cout << lesser("Aaron", "Zeke") << endl; cout << lesser("Aaron", "Zeke") << endl; return 0; return 0; } Optional Demo: funtemps.cpp
10
17-10 What is going on? TheClass is a template It becomes whatever class name (int, string,.. ) is passed to the function Therefore, the arguments and the return type are all of the same type For each argument type, the C++ compiler generates a function with that type the previous main function forced the C++ compiler to generate four unique functions, each with a different type of parameter to matches the return type
11
17-11 The four (4) functions you get int lesser(int a, int b) { int result; if(a < b) result = a; else result = b; return result; } double lesser(double a, double b) { double result; if(a < b) result = a; else result = b; return result; } char lesser(char a, char b) { char result; if(a < b) result = a; else result = b; return result; } char* lesser(char* a, char* b) { char* result; if(a < b) result = a; else result = b; return result; }
12
17-12 17.2 Class Templates You can make a class accept a template parameter The template parameter name can be used throughout an entire class This allows for collections of any class, for example can have a bag of ints, doubles, books,... just like the vector class that must have the class name between just like the vector class that must have the class name between
13
17-13 Class Templates Class templates are just like function templates except they are followed by a class definition rather than a function definition template template class-definition This can add a lot of code to the member function implementations unless you implement functions in the class
14
17-14 Consider a vector class template template class vector { public: vector(); vector(); vector(int initCapacity); vector(int initCapacity); vector(int initCapacity, vector(int initCapacity, VectorElementType initialValue); VectorElementType initialValue); vector(const vector & source); vector(const vector & source); ~vector(); ~vector(); //... //...private: VectorElementType* x; // Pointer to first of many VectorElementType* x; // Pointer to first of many};
15
17-15 When vector objects are constructed The template argument passed up during construction replaces the class parameter you get pointers to any type vector a3(7); VectorElementType* x; bankAccount* x; bankAccount* x; vector a4(7); VectorElementType* x; track* x; track* x; vector a3(7); VectorElementType* x; int* x; int* x; vector a3(7); VectorElementType* x; double* x; double* x;
16
17-16 17.2.1 Member Function Templates When a class has been defined with a template parameter, all member functions automatically become template functions This means that the member functions must be preceded by the same syntax template template class-name ::member-function-name(parameters) { //... member function implementation //... member function implementation}
17
17-17 Examples This means a lot of stuff must be written before the member function implementations even if there is no reference to the template parameter four words and two sets of even if there is no reference to the template parameter four words and two sets of template template int vector ::capacity() const { return my_capacity; return my_capacity; } Extra Code
18
17-18 17.2.2 A Simple Class with a Template To avoid all that ugly extra syntax, consider a class definition that also implements the member functions replace ; with the function body between { and } The following class only demonstrates the use of templates within a class the class must define << since that operator is applied to any class of object passed to construct a Silly object
19
17-19 A Simple Generic Class template template class Silly { // pre: Type must define ostream << public: Silly(Type initValue) Silly(Type initValue) { value = initValue; value = initValue; } void display() void display() { // pre: Type can be output with cout << { // pre: Type can be output with cout << cout << "The value: " << value << endl; cout << "The value: " << value << endl; }private: Type value; Type value;};
20
17-20 The type between cause another class creation #include #include using namespace std; #include "Silly" // For class Silly // This main function will cause three classes to // be generated by the compiler with Type replaced // by int, double, and string int main() { Silly anInt(-999); Silly anInt(-999); Silly aDouble(1.23e-02); Silly aDouble(1.23e-02); Silly aString("abcdefg"); Silly aString("abcdefg"); anInt.display(); anInt.display(); aDouble.display(); aDouble.display(); aString.display(); aString.display(); return 0; return 0;} Output The value: -999 The value: 0.0123 The value: abcdefg The value: abcdefg
21
17-21 17.3 A Generic bag Class Chapter 11 presented a container class named bag for storing a collection of objects that bag class required a typedef before the #include to indicate what the bag could store This section presents a generic bag class bag identifier ; bag identifier ; This is what the C++ standard library used for its container classes like vector and list Optional Demo: p660.cpp
22
17-22 BagElementType Now the BagElementType is a template parameter--it is known thoughout the class template template class bag { public: bag(); bag(); //... //... void add(BagElementType newElement); void add(BagElementType newElement); // post: Add newElement to this bag and increase // post: Add newElement to this bag and increaseprivate: BagElementType* my_data; // Pointer to first... BagElementType* my_data; // Pointer to first... //... //...};
23
17-23 Implement member functions with template Any member function in bag must get the extra templates synytax when implemented outside of the class even if BagElementType is not used in the function notice that add checks the capacity, extra memory is allocated when the bag is full template template void bag ::add(BagElementType newElement) { // First check to see if we need to grow the bag if(my_size >= my_capacity) if(my_size >= my_capacity) { // Inadequate capacity so double the capacity { // Inadequate capacity so double the capacity my_capacity = 2 * my_capacity; my_capacity = 2 * my_capacity; //... //...
24
17-24 17.3.3 The Copy Constructor This bag class uses a pointer need a copy constructor and a destructor This copy constructor will perform deep copying do not just copy the pointer It too requires the extra template syntax see next slide
25
17-25 The Copy Constructor for passing bag objects as arguments template template bag ::bag(const bag & source) { // Copy the data members (memberwise copy) // Copy the data members (memberwise copy) my_size = source.my_size; my_size = source.my_size; my_index = source.my_index; my_index = source.my_index; my_capacity = source.my_capacity; my_capacity = source.my_capacity; // Allocate the memory for the new bag // Allocate the memory for the new bag my_data = new BagElementType[my_capacity]; my_data = new BagElementType[my_capacity]; // Copy all values from source to destination // Copy all values from source to destination for(int j = 0; j < my_capacity; j++) for(int j = 0; j < my_capacity; j++) { // Deep copy copies all elements, not just the pointer { // Deep copy copies all elements, not just the pointer my_data[j] = source.my_data[j]; my_data[j] = source.my_data[j]; }}
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.