UCLA PIC 10 B Problem Solvig usig C++ Programmig Ivo Diov, Asst. Prof. i Mathematics, Neurology, Statistics Istructor: Teachig Assistat: Suzae Nezzar, Mathematics Chapter 13 Templates for More Abstractio Uiversity of Califoria, Los Ageles, Summer 2001 http://www.math.ucla.edu/~diov/10b.1.011/ 1 2 Templates for More Abstractio Templates for More Abstractio Templates for Algorithm Abstractio g Templates for Fuctios Templates for Data Abstractio g Sytax for Class Templates The C++ template facility provides the ability to defie fuctios ad classes that have parameter that carry type iformatio. This is the geeric facility of C++. A geeric facility allows code to be writte oce the reused with differet types. The classes ad fuctios you will defie i this chapter are much more geeral tha before. It is widely held that a geeric facility is oe of the most importat ideas i programmig. 3 4 13.1 Templates for Algorithm Abstractio(1 of 2) Display 13.1 A Fuctio Template // Program to demostrate a fuctio template. #iclude <iostream> usig amespace std; I may fuctios that are writte, the algorithm is more geeral tha the implemetatio. This swap algorithm oly works for it values: void swap ( it & v1, it & v2) { it temp = v1; v1 = v2; v2 = temp; If it is replaced by double, we have aother valid swap routie. I fact, ay type ca be used if the type has a copy costructor ad assigmet defied. Do you see where these are eeded? 5 // Iterchages the values of variable1 ad variable2. void swap_values(t& variable1, T& variable2) { T temp; temp = variable1; variable1 = variable2; variable2 = temp; it mai( ) { it iteger1 = 1, iteger2 = 2; cout << "Origial iteger values are " << iteger1 << " " << iteger2 << edl; swap_values(iteger1, iteger2); cout << "Swapped iteger values are " << iteger1 << " " << iteger2 << edl; char symbol1 = 'A', symbol2 = 'B'; cout << "Origial character values are " << symbol1 << " " << symbol2 << edl; swap_values(symbol1, symbol2); cout << "Swapped character values are " << symbol1 << " " << symbol2 << edl; retur 0; 6 1
Templates for Fuctios(1 of 3) Templates for Fuctios(2 of 3) Display 13.1 shows the sytax for a C++ template fuctio, swap_values. The defiitio ad prototype begi with the lie This is called the template prefix. It tells the compiler that the defiitio that follows is a template. It also provides a defiitio for the type parameter T withi the template defiitio. The word class i the template prefix meas type. The template defiitio provides a defiitio of the fuctio for every possible type from which oly the required defiitio is selected. 7 Callig a template fuctio is easy. Write code as if the eeded defiitio were preset. Whe the compiler sees a fuctio call, it searches for a ordiary fuctio ame with a sequece of types i the parameter list. If a defiitio that matches the ame ad parameter list types is foud, that oe is used. If o matches are preset, the the compiler uses a template fuctio defiitio with the correct umber of parameters. If the compiler ca deduce the types of the type parameters, the the compiler uses the template to produce a fuctio with the deduced types. The rules are more complicated, but this is sufficiet i 8 most simple situatios. Templates for Fuctios(3 of 3) Pitfall: Compiler Complicatios We put the template defiitio above before the mai Some compilers do ot allow separate compilatio of fuctio, ad used o prototype. templates. You will likely eed to iclude your template A template fuctio may have a template prototype, but defiitio with your code that uses it. separatig the prototype from the defiitio is ot usually At least the prototype must precede use of the template possible with today's compiler techology. fuctio. The safest strategy is to put the template defiitio i the The safest strategy is to put the template defiitio i the same file where it is used, prior to use of the template. same file where it is used, prior to use of the template. Most template fuctios eed oly oe template Some C++ compilers have pragmas that are ot portable to other compilers. parameter. Some C++ compilers have special, additioal requiremets Use of more tha oe type parameter is always possible. for templates. Read your C++ compiler maual or cosult a Cosider, for example: local expert if you have trouble. You may eed to set template <class T1, class T2> 9 optios or rearrage the order of the template defiitios. 10 Fuctio Template (1 of 2) The fuctio defiitio ad the fuctio prototype for a fuctio template are each prefaced with the followig: template<class Type_Parameter> The prototype (if used) ad defiitio are the the same as ay ordiary fuctio prototype ad defiitio, except that the Type_Parameter ca be used i place of a type. For example, the followig is a prototype for a fuctio template: template<class T1, class T2> void show_stuff( it stuff1, T1 stuff2, T2 stuff3); // Prototype Def.. template<class T1, class T2 > // Fuctio Def void show_stuff( it stuff1, T1 stuff2, T2 stuff3) { cout << stuff1 << edl << stuff2 << edl << stuff3 << edl; Fuctio Template (2 of 2) The fuctio give i this example is equivalet to havig oe fuctio prototype ad oe fuctio defiitio for each possible type ame. The type ame is substituted for the type parameter (which are T1, T2 i the example here.) For istace cosider the followig fuctio call: show_stuff(2, 3.3, ch); Whe this fuctio call is executed, the compiler uses the fuctio defiitio obtaied by replacig T1 with the type ame double, ad T2 by char type. A separate defiitio will be produced for each differet type for which you use the template, but ot for ay types you do ot use. Oly oe defiitio should be geerated regardless of the umber of times you use the template. NOTE: Some compilers require special istructios to esure that oly oe copy of the fuctio is geerated. You wo't see that problem i this course. 2
Algorithm Abstractio As we saw i our discussio of the swap_values fuctio, there is a very geeral algorithm for iterchagig the values of two variables ad this more geeral algorithm applies to variables of ay type. Usig a fuctio template we were able to express this more geeral algorithm i C++. This is a very simple example of algorithm abstractio. Whe we say we are usig algorithm abstractio we mea that we are expressig our algorithms i a very geeral way so that we ca igore icidetal detail ad cocetrate o the substative part of the algorithm. Fuctio template are oe feature of C++ that supports algorithm abstractio. 13 Programmig Example: A Geeric Sortig Fuctio(1 of 2) Sortig is a applicatio for templates. Nothig i a sort routies that work by swappig depeds o the type except for havig a copy costructor ad a overloaded < operator ad a overloaded assigmet operator. Examiatio of the defiitio of sort from Display 13.1 show that the base type of the array is ever used i ay sigificat way. The fuctio idex_of_smallest also does ot deped o the base type of the array. By replacig several istaces of it by a type parameter, the fuctio sort ca sort a array of ay type provided that type provides the overloaded operators as outlied above. 14 Programmig Example: A Geeric Sortig Fuctio (2 of 2) The behavior of the < operator must be examied. For example, for letters of the alphabet: With a pair of upper case letters or a pair of lower case letters, < works as expected. Letters later i the alphabet are greater (this is our lexicographical orderig). For mixed upper ad lower case letters, ay upper case letter is less tha ay lower case letter, ad coversely, ay lower case letter is greater tha ay upper case letter. The reaso is that for char values, < compares the ASCII ecodig. (Except oly if your computer uses a differet stadard character table like EBCDIC, which oly happes with IBM maiframes ad a very few miicomputers.) 15 Display 13.2 A Geeric Sortig Fuctio (1 of 2) // This is file sortfuc.cpp void swap_values(t& variable1, T& variable2) { T temp; temp = variable1; variable1 = variable2; variable2 = temp; it idex_of_smallest(cost T a[ ], it start_idex, it umber_used) { T mi = a[start_idex]; it idex_of_mi = start_idex; for (it idex = start_idex + 1; idex < umber_used; idex++) if (a[idex] < mi) { mi = a[idex]; idex_of_mi = idex; // mi is the smallest of a[start_idex] through a[idex] retur idex_of_mi; 16 Display 13.2 A Geeric Sortig Fuctio (2 of 2) void sort(t a[ ], it umber_used) { it idex_of_ext_smallest; for(it idex = 0; idex < umber_used - 1; idex++) { // Place the correct value i a[idex]: idex_of_ext_smallest = idex_of_smallest(a, idex, umber_used); swap_values(a[idex], a[idex_of_ext_smallest]); //a[0] <= a[1] <=...<= a[idex] are the smallest of the origial array //elemets. The rest of the elemets are i the remaiig positios. 17 Display 13.3 Usig a Geeric Sortig Fuctio (1 of 2) // Demostrates a geeric sortig fuctio. #iclude <iostream> usig amespace std; // The file sortfuc.cpp defies the followig fuctio: void sort(t a[ ], it umber_used); // Precoditio: umber_used <= declared size of the array a. // The array elemets a[0] through a[umber_used - 1] have values. // Postcoditio: The values of a[0] through a[umber_used - 1] have // bee rearraged so that a[0] <= a[1] <=... <= a[umber_used - 1]. #iclude "sortfuc.cpp it mai( ) { it i; it a[10] = {9, 8, 7, 6, 5, 1, 2, 3, 0, 4; cout << "Usorted itegers:\"; for (i = 0; i < 10; i++) cout << a[i] << " "; cout << edl; sort(a, 10); cout << "I sorted order the itegers are:\"; for (i = 0; i < 10; i++) cout << a[i] << " "; cout << edl; 18 3
Display 13.3 Usig a Geeric Sortig Fuctio (2 of 2) double b[5] = {5.5, 4.4, 1.1, 3.3, 2.2; cout << "Usorted doubles:\"; Programmig Tip: How to defie Templates for (i = 0; i < 5; i++) cout << b[i] << " "; cout << edl; sort(b, 5); cout << "I sorted order the doubles are:\"; 1. We created the template for Display 13.2 by writig a ordiary fuctio that sorts for base type it. 2. We created the template by replacig the base type of for (i = 0; i < 5; i++) cout << b[i] << << edl; the array with type parameter T. char c[7] = {'G', 'E', 'N', 'E', 'R', 'I', 'C'; cout << "Usorted characters:\"; 3. This process has two advatages: for (i = 0; i < 7; i++) cout << c[i] << << edl; 1. The ordiary fuctio is cocrete which is easier to sort(c, 7); visualize. cout << "I sorted order the characters are:\"; for (i = 0; i < 7; i++) cout << c[i] << << edl; retur 0; 19 2. You are dealig with fewer details. You do't have to worry about template sytax rules. 20 13.2 Templates for Data Abstractio Sytax for Class Templates Sytax for Class Templates(1 of 3) class template sytax requires a template prefix: Oce the class template is defied, you ca defie objects of the template class: where T is a type ame. As i fuctio templates, T ca be a built-i type or a class. Pair<it> score1; Example: Pair<char> seats1; class Pair Usig the parameterized costructor { Pair<it> score2(1,2); public: Pair( ( ); Pair<char> seats2('a', 'B ); Pair(T first_value, T secod_value); void set_elemet(it positio, T value); T get_elemet(it positio) cost; The Objects are like ay other objects. We apply private: the member fuctio set_elemet: T first; score1.set_elemet(1,3); T secod; ; 21 score1.set_elemet(2,0); 22 Sytax for Class Templates(2 of 3) Sytax for Class Templates(3 of 3) Note the class ame Pair<T> is used for scope resolutio, ot just Pair. // Uses iostream ad cstdlib: void Pair<T>::set_elemet( set_elemet(it positio, T value) { if (positio = 1) first = value; else if (positio = 2) secod = value; else { cout << "Error: Illegal pair positio.\"; "; exit(1); 23 The costructors are: Pair<T>::Pair( ) { //I the default costructor,, you first = T( ); //ca iitialize first ad secod secod = T( ); //usig the default T object //costructor, whatever it may be. Pair<T>::Pair(T first_value, T secod_value) { first = first_value; secod = secod_value; As i the member fuctio, the class ame for scope resolutio must be Pair<T>, ot just Pair. 24 4
Class Template Sytax (1 of 2) The class defiitio ad the defiitios of the member fuctios are prefaced with the followig: template<class Type_Parameter> The class ad member fuctio defiitios are the the same as for ay ordiary class except that Type_Parameter ca be used i p lace of a type. For example, the followig is the begiig of a class template defiitio: class Pair { public: Pair( ); Pair( T first_value, T secod_value);... ; 25 Class Template Sytax (2 of 2) Member fuctios ad overloaded operators are the defied as fuctio templates. For example, the defiitio of the two argumet costructor for the above sample class template would begi: Pair<T>::Pair(T first_value, T secod_value) {... 26 Type Defiitios You ca specialize a class template by givig a type argumet to the class ame as i the followig example: Programmig Example: A Array Class Pair<it> Display 13.4 cotais the iterface for a class template amed The specialized class ame, like Pair<it>, ca the be used just like List whose objects are lists of a user specified type which may be ay class ame. It ca be used to declare objects or to specify the type built-i or user defied. of a formal parameter. Display 13.5 cotais a demostratio program that uses the List You ca defie a ew class type ame that has the same meaig as a template class. The purpose is to illustrate sytax. specialized class template ame, such as Pair<it>. The sytax for Display 13.6 cotais the implemetatio of the List class such a defied class type ame is: template. The data is stored iterally as a dyamic array. typedef Class_Name<Type_argumet> New_Type_Name; Members provided are the default costructor, a destructor, For example: legth, add, full, ad erase. typedef Pair<it> PairOfIt; Notice the overloaded isertio operator (<<), whichweuseto The typeame PairOfIt ca the be used to declare objects of type output a object of template class List. Pair<it> as i this example: Whe we specify a parameter of List class type i a template PairOfIt pair1, pair2; fuctio, whether a member or stadaloe, we use List<T>. The type ame PairOfIt ca also be used to specify the type of a Whe we specify a template List parameter type that holds it formal parameter. 27 27 values, the type is specified as List<it>. 28 Display 13.4 Iterface for the Class Template List (1 of 2) // FILE: list.h. // This is the INTERFACE for the class List. List objects ca hold items of ay // type where operators << ad = are defied. All the items o ay oe list must // be of the same type. Declare a list of up to max items of type Type_Name as: // List<Type_Name> the_object(max); #ifdef LIST_H #defie LIST_H #iclude <iostream> usig amespace std; amespace savitchlist { class List { public: List(it max); // Iitializes the object to a empty list that ca // holduptomaxitemsoftypet. ~List( ); // Returs all the dyamic memory used by the object to the heap. it legth( ) cost; // Returs the umber of items o the list. 29 Display 13.4 Iterface for the Class Template List (2 of 2) // FILE: list.h. void add(t ew_item); // Precoditio: The list is ot full. // Postcoditio: The ew_item has bee added to the list. itfull()cost; // Returs true if the list is full. void erase( ); // Removes all items from the list so that the list is empty. fried ostream& operator <<(ostream& outs, cost List<T>& the_list); // Overloads the << operator so it ca be used to output the cotets // of the list. The items are output oe per lie. // Precoditio: If outs is a file output stream, the outs has already // bee coected to a file. private: T *item; //poiter to the dyamic array that holds the list. it max_legth; //max umber of items allowed o the list. it curret_legth; //umber of items curretly o the list. ; // savitchlist #edif //LIST_H 30 5
Display 13.5 Program usig the List class Template // Program to demostrate use of the class template List. #iclude <iostream> #iclude "list.h" #iclude "list.cxx" usig amespace std; usig amespace savitchlist; it mai( ) { List<it> first_list(2); first_list.add(1); first_list.add(2); cout << "first_list = \" << first_list; List<char> secod_list(10); secod_list.add('a'); secod_list.add('b'); secod_list.add('c'); cout << "secod_list = \" << secod_list; retur 0; 31 Display 13.6 Implemetatio of List (1 of 3) // FILE: list.cpp This is the IMPLEMENTATION of the class template List. // The iterface for this class is list.h. #ifdef LIST_CXX #defie LIST_CXX #iclude <iostream> #iclude <cstdlib> #iclude "list.h" //This is ot eeded whe used as we are usig this file, //but the #ifdef i list.h makes it safe. usig amespace std; amespace savitchlist { // Uses cstdlib: List<T>::List(it max) { max_legth = max; curret_legth = 0; delete [ ] item; item = ew T[max]; if (item == NULL) { cout << "Error: Isufficiet memory.\"; exit(1); 32 Display 13.6 Implemetatio of List (2 of 3) List<T>::~List( ) { delete [ ] item; it List<T>::legth( ) cost { retur (curret_legth); Display 13.6 Implemetatio of List (3 of 3) it List<T>::full( ) cost { retur (curret_legth >= max_legth); void List<T>::erase( ) { curret_legth = 0; //Uses iostream ad cstdlib: void List<T>::add(T ew_item) { if(full()) { cout << "Error: addig to a full list.\"; exit(1); else { item[curret_legth] = ew_item; curret_legth = curret_legth + 1; 33 //Uses iostream: ostream& operator <<(ostream& outs, cost List<T>& the_list) { for (it i = 0; i < the_list.curret_legth; i++) outs << the_list.item[i] << edl; retur outs; // savitchlist #edif // LIST.CPP Notice that we have eclosed all the template // defiitios i #ifdef... #edif. 34 Chapter Summary Usig fuctio templates you ca defie fuctios that have a parameter for a type. Usig class templates you ca defie a class with a type parameter for sub-parts of the class. 35 6