1 / 40

Template Classes and Functions

Template Classes and Functions. Andy Wang Object Oriented Programming in C++ COP 3330. Function Templates. A function template can perform the same algorithm for different types without specifying the types in advance

sallyp
Télécharger la présentation

Template Classes and Functions

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Template Classes and Functions Andy Wang Object Oriented Programming in C++ COP 3330

  2. Function Templates • A function template can perform the same algorithm for different types without specifying the types in advance • Example: a function that computes the maximum for three different integers int maximum(int a, int b, int c) { int max = a; if (b > max) max = b; if (c > max) max = c; return max; }

  3. Function Templates • However, this function only works for int variables (or types that can be automatically converted to int) • What if we wanted to compare variables with the type double? • Do we have to write a new function? • A function template allows this problem to be solved easily, with only one function

  4. Templated Version of Maximum • http://www.cs.fsu.edu/~myers/deitel5c++/ch06/Fig06_26_27/

  5. maximum.h template<class T> T maximum(T value1, T value2, T value3) { T maximumValue = value1; if (value2 > maximumValue) maximumValue = value 2; if (value3 > maximumvalue) maximumValue = value 3; return maximumValue; }

  6. figure06_27.cpp #include <iostream> #include “maximum.h” using namespace std; int main() { int int1, int2, int3; cout << “Input three integer values: “; cin >> int1 >> int2 >> int3; cout << “The maximum integer value is: “; << maximum(int1, int2, int3);

  7. figure06_27.cpp double double1, double2, double3; cout << “\n\nInput three double values: “; cin >> double1 >> double2 >> double3; cout << “The maximum double value is: “; << maximum(double1, double2, double3); char char1, char2, char3; cout << “\n\nInput three characters: “; cin >> char1 >> char2 >> char3; cout << “The maximum character value is: “ << maximum(char1, char2, char3); return 0; }

  8. Another Example • http://www.cs.fsu.edu/~myers/deitel5c++/ch14/Fig14_01/fig14_01.cpp • This is a function template that prints the contents of the array template<class T> void printArray(const T*array, constint count) { for (int j = 0; j < count; j++) cout << array[j] << “ “; cout << endl; } • This function will work on arrays of any class type when an appropriate insertion operator << has been defined

  9. Another Example int main() { constintaCount = 5; constintbCount = 7; constintcCount = 6; int a[aCount] = {1, 2, 3, 4, 5}; double b[bCount] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7}; char c[cCount] = “HELLO”; cout << “Array a contains: “ << endl; printArray(a, aCount); cout << “Array b contains: “ << endl; printArray(b, bCount); cout << “Array c contains: “ << endl; printArray(c, cCount); return 0; }

  10. Example: Swap • http://www.cs.fsu.edu/~myers/savitch3c++/Ch16/16-01.cpp

  11. 16-01.cpp #include <iostream> using namespace std; template<class T> void swapValues(T &variable1, T &variable2) { T temp; temp = variable1; variable1 = variable2; variable2 = temp; }

  12. 16-01.cpp int main() { int integer1 = 1, integer2 = 2; cout << “Original integer values are “ << integer1 << “ “ << integer2 << endl; swapValues(integer1, integer2); cout << “Swapped integer values are “ << integer1 << “ “ << integer2 << endl; char symbol1 = ‘A’, symbol2 = ‘B’; cout<< "Original character values are: " << symbol1 << " " << symbol2 << endl; swapValues(symbol1, symbol2); cout<< "Swapped character values are: " << symbol1 << " " << symbol2 << endl; return 0; }

  13. Making Container Classes Versatile • Here is an example of a class that uses array-based storage to maintain a list of integers • http://www.cs.fsu.edu/~myers/cop3330/examples/templates/simplelist1/

  14. simplelist1.h constint MAX = 10; class SimpleList { public: SimpleList() { current = 0; } bool Insert(int item); intGetElement(unsigned int n); void Print(); intGetSize() { return current; } private: int array[MAX]; int current; };

  15. simplelist1.cpp #include <iostream> #include “simplelist1.h” using namespace std; bool SimpleList::Insert(int item) { if (current < MAX) { array[current++] = item; return true; } else return false; } intSimpleList::GetElement(unsigned int n) { if (n >= MAX) n = MAX – 1; return array[n]; }

  16. simplelist1.cpp void SimpleList::Print() { if (current == 0) cout << “Empty List”; return; for (int j = 0; j < current – 1; j++) cout << array[j] << ‘ ‘; cout << array[current - 1]; }

  17. Suppose… • We want to have a class that can store a list of double values or a list of characters • We could write a similar class for each for each new type • A common C trick is to use a typedefto create a simple user-defined type • For example, we can define mytype to be a synonym for the type int • typedefintmytype; • We can also define mytype as double • typedef double mytype;

  18. By doing so… • We can define a class using mytype • To change an int array to a double array, just change the typedef for mytype, and recompile • http://www.cs.fsu.edu/~myers/cop3330/examples/templates/simplelist2/

  19. simplelist2.h constint MAX = 10; typedefintmytype; class SimpleList { public: SimpleList() { current = 0; } bool Insert(mytype item); mytypeGetElement(unsigned int n); void Print(); intGetSize() { return current; } private: mytypearray[MAX]; intcurrent; };

  20. simplelist2.cpp #include <iostream> #include "simplelist2.h" using namespace std; bool SimpleList::Insert(mytype item) { if (current < MAX) { array[current++] = item; return true; } else return false; } mytypeSimpleList::GetElement(unsigned int n) { if (n >= MAX) n = MAX - 1; return array[n]; }

  21. simplelist2.cpp void SimpleList::Print() { if (current == 0) { cout<< "Empty List"; return; } for (inti= 0; i < current - 1; i++) cout << array[i] << ' '; cout << array[current - 1]; }

  22. Class Templates • With class templates, we can make this class work with different types without altering and recompiling the code • To make a class into a template, prefix the class definition with the syntax template<class T> • T is a type parameter, and it can have any name • When the class is instantiated, we fill in an appropriate type • Use the same prefix on the definitions of the member functions

  23. Class Templates • For member functions, the name of the class will be className<T>::memberName • In the SimpleList example, the type of the array is T, which will be filled in when an object is created • Also, in the main program, we must #include the actual definition file, in addition to the class declaration • The compiler creates a different version of the class for each type that is used • Thus, either the entire class should be written in the header file, OR the .cpp file should be #included #include “simplelist3.cpp”

  24. SimpleListClass Template Example • http://www.cs.fsu.edu/~myers/cop3330/examples/templates/simplelist3/

  25. simplelist3.h constint MAX = 10; template<class T> class SimpleList { public: SimpleList() { current = 0; } bool Insert(Titem); TGetElement(unsigned int n); void Print(); intGetSize() { return current; } private: Tarray[MAX]; intcurrent; };

  26. simplelist3.cpp #include <iostream> #include "simplelist3.h" using namespace std; #ifndef _SIMPLELIST_CPP #define _SIMPLELIST_CPP template<class T> bool SimpleList<T>::Insert(T item) { if (current < MAX) { array[current++] = item; return true; } else return false; }

  27. simplelist3.cpp template<class T> TSimpleList<T>::GetElement(unsigned int n) { if (n >= MAX) n = MAX - 1; return array[n]; } template<class T> void SimpleList<T>::Print() { if (current == 0) { cout<< "Empty List"; return; } for (inti= 0; i < current-1; i++) cout << array[i] << ' '; cout << array[current - 1]; } #endif

  28. main.cpp #include <iostream> #include “simplelist3.cpp” using namespace std; int main() { SimpeList<int> list1; for (int j = 0; j < 8; j++) list1.Insert(i*3); cout << “Element at index 4 = “ << list1.GetElement(4) << endl; cout << “Entire list is:\n”; list1.Print(); cout << “\n\n”;

  29. main.cpp SimpleList<double> list2; for (int j = 0; j < 10; j++) list2.Insert(j * 1.1); cout << “Element at index 6 = “ << list2.GetElement(6) << endl; cout << “Entire list is:\n”; list2.Print(); cout << “\n\n”; return 0; }

  30. Dynamic List Example • http://www.cs.fsu.edu/~myers/cop3330/examples/templates/tlist/

  31. tlist.h #include <iostream> Using namespace std; #ifndef _LIST_H #define _LIST_H template<class T> class List { public: List(int s = 10); ~List(); List(const List<T> &); List &operator=(const List<T> &); void Insert(T item); T GetElement(unsigned int n); void Print(ostream&os);

  32. tlist.h private: T* data; int size, max; void Clone(const List<T> &); void Resize(intnewsize); }; template<class T> List<T>::List(int s) { size = 0; max = s; if (max <= 0) { data = 0; max = 0; } else data = new T[max]; }

  33. tlist.h template<class T> List<T>::~List() { if (data) delete [] data; } template<class T> List<T>::List(const List<T> &L) { Clone(L); } template<class T> List<T> &List<T>::operator=(const List<T> &L) { if (this != &L) { if (data) delete [] data; Clone(L); } return *this; }

  34. tlist.h template<class T> void List<T>::Insert(T item) { if (max == size) Resize(max + 5); data[size] = item; size++; } template<class T> T List<T>::GetElement(unsigned int n) { if (n >= size) n = size – 1; return data[n]; } template<class T> void List<T>::Print(ostream&os) { if (size == 0) os << “List empty”; for (int j = 0; j < size – 1; j++) os << data[j] << “, “; os << data[size - 1]; }

  35. tlist.h template<class T> void List<T>::Resize(intnewsize) { max = newsize; T *temp = new T[max]; for (int j = 0; j < size; j++) temp[j] = data[j]; if (data != 0) delete [] data; data = temp; } template<class T> void List<T>::Clone(const List<T> &L) { max = L.max; size = L.size; date = new T[max]; for (int j = 0; j < size; j++) data[j] = L.data[j]; }

  36. main.cpp #include <iostream> #include “tlist.h” using namespace std; int main() { List<int> tests; int gr; cout << “Enter some grades (negative to quite):\n “; do { cin >> gr; if (gr >= 0) tests.Insert(gr); } while (gr >= 0); cout << “The 7th element is: “ << test.GetElement(7) << endl; cout << “The 2nd element is: “ << test.GetElement(2) << endl;

  37. main.cpp cout << “Here is the list of grades: \n\n”; test.Print(); cout << “\n\nCreating a list of doubles\n”; List<double> stats(0); double num; cout << “Enter some floating point numbers (negative to quit\n”; do { cin >> num; if (num >= 0) stats.Insert(num); } while (num >= 0);

  38. main.cpp cout << "The 6th element is: " << stats.GetElement(6) << '\n'; cout<< "The 2nd element is: " << stats.GetElement(2) << '\n'; cout<< "Here is the list of doubles:\n\n"; stats.Print(cout); cout<< "\n\n"; return 0; }

  39. main2.cpp #include <iostream> #include <string> #include “tlist.h” using namespace std; template<class T> void TestList(List<T> theList, string label, int val1, int val2) { T gr; cout << “Enter some “ << label << “ (negative to quite):\n “; do { cin >> gr; if (gr >= 0) theList.Insert(gr); } while (gr >= 0)

  40. main2.cpp cout<< "Element " << val1 << " is: " << theList.GetElement(val1) << '\n'; cout<< "Element " << val2 << " is: " << theList.GetElement(val2) << '\n'; cout<< "Here is the list of " << label << ":\n\n"; theList.Print(cout); } int main() { List<int> tests; List<double> stats(0); TestList(tests, "grades", 7, 2); TestList(stats, "floats", 6, 2); }

More Related