1 / 33

Week 10

Week 10. Hand in Lab 6 Templates Lab 7. Templates. Say you’ve written a function like this: int max(int a, int b) { if (a > b) return a; return b; } But now you need another: max(float x, float y). Repetitive code. Max, min, compare Squaring, cubing, combining

tracey
Download Presentation

Week 10

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. Week 10 • Hand in Lab 6 • Templates • Lab 7 Kate Gregorywith material from Deitel and Deitel

  2. Kate Gregorywith material from Deitel and Deitel

  3. Templates • Say you’ve written a function like this: int max(int a, int b) { if (a > b) return a; return b; } • But now you need another:max(float x, float y) Kate Gregorywith material from Deitel and Deitel

  4. Repetitive code • Max, min, compare • Squaring, cubing, combining • Sorting, normalizing, converting • The type-safety of C++ makes these work well, but can require a lot of code Kate Gregorywith material from Deitel and Deitel

  5. You have choices • Copy and paste • Error prone • Hard to ripple changes through if you change the original • Use #define • Awful because of side effects • Dangerous casts Kate Gregorywith material from Deitel and Deitel

  6. #define macros #define sq(a) a * a int x = sq(2); int y = sq(1+1); • Expands to 1 + 1 * 1 + 1 • 3! Kate Gregorywith material from Deitel and Deitel

  7. #define macros int j=sq(i++); • Expands to i++ * i++ • Answer compiler-dependent • i will be incremented twice • Side effects of macros can be reduced with many extra () but never eliminated • Macros are not a safe road to genericity Kate Gregorywith material from Deitel and Deitel

  8. Dangerous casts void* max(void* a, void* b) • Cast everything you pass to it and everything you get back • Must de-reference pointers • Can’t stop people comparing apples and oranges • Throwing away the entire type system: and for what? The compiler is your friend. Kate Gregorywith material from Deitel and Deitel

  9. Template Functions template<class T> T biggest(T a, T b) { if ( a > b) return a; return b; } • Here T is a placeholder. You can name your placeholders whatever you like Kate Gregorywith material from Deitel and Deitel

  10. Using a template function cout << "biggest of 4 and 5 is " << biggest(4,5) << endl; cout << "biggest of 4.1 and 5.2 is " << biggest(4.1,5.2) << endl; Kate Gregorywith material from Deitel and Deitel

  11. Using a template function Holder h1(4); Holder h2(5); cout << "biggest of h1 and h2 is: " << biggest(h1,h2) << endl; Kate Gregorywith material from Deitel and Deitel

  12. Templates and Operators • The biggest function will only work if Holder has overloaded the > operator • The code using biggest will only work if Holder has overloaded the << operator • Without operator overloading, one template couldn’t work with both fundamental types (eg int) and user defined types (ie classes). • Operator overloading is vital to type-safe genericity Kate Gregorywith material from Deitel and Deitel

  13. What happens here? cout << "biggest of Hello and 2 is " << biggest("Hello", 2); • Compiler error. • Eg: error C2782: 'T biggest(T,T)' : template parameter 'T' is ambiguous Kate Gregorywith material from Deitel and Deitel

  14. What happens here? cout << "biggest of Hello and World is " << biggest("Hello", "World"); cout << "biggest of A and XYZ is " << biggest("A", "XYZ") << endl; cout << "biggest of ABC and Z is " << biggest("ABC", "Z") << endl; • The results are actually compiler specific • Visual C++ 6: second literal string is always “biggest” • Visual C++.NET: first literal string is always “biggest” • It’s based on the numerical value of the pointer Kate Gregorywith material from Deitel and Deitel

  15. More string comparisons char* Hello1 = "Hello"; char* World = "World"; char* Hello2 = "Hello"; cout << "biggest of Hello1 and World is " << biggest(Hello1,World) << endl; • World cout << "biggest of Hello2 and World is " << biggest(Hello2,World) << endl; • Hello Kate Gregorywith material from Deitel and Deitel

  16. Providing a Specific Implementation • What if I wanted biggest to use string length when passed a char* ? template<> char* biggest(char* a, char* b) { if (strlen(a) > strlen(b) ) return a; return b; } Kate Gregorywith material from Deitel and Deitel

  17. Class Templates • Consider writing an Array class like the one presented earlier in this course • self-growing when users attempt to set values past the end of the array • Overloading operator[], operator<< • Preventing access before the beginning of the array • But an Array of What? Kate Gregorywith material from Deitel and Deitel

  18. More Duplication • You could write IntArray, FloatArray, StringArray, and so on • A lot of duplicate work • Or you could write a generic array that worked with void* • What would stop people from mixing object types within an array? • Annoying to cast everything in and out of the array • Couldn’t put literal values (Eg 3) in the array because you can’t take their address Kate Gregorywith material from Deitel and Deitel

  19. Solution template<class C> class Array { private: C* data; int length; public: Array(): data(NULL),length(0) {}; C& operator[](int i); friend ostream& operator<<(ostream& o, const Array& a); }; Kate Gregorywith material from Deitel and Deitel

  20. How do you implement the functions? template<class C> int Array<C>::getlength() { return length; } Kate Gregorywith material from Deitel and Deitel

  21. How do you implement the functions? template<class C> ostream& operator<<(ostream& o, const Array<C>& a) { for (int i=0;i<a.length;i++) { o << a[i] << “ “; } return o; }; Kate Gregorywith material from Deitel and Deitel

  22. How do you use a template? Array<int> ai; ai[0] = 1; ai[3] = 2; cout << ai[2] << endl; cout << ai[5] << endl; Kate Gregorywith material from Deitel and Deitel

  23. Templates work with classes and fundamental types too Array<Holder> ah; ah[0] = h1; ah[2] = h2; cout << ah[0] << endl; cout << ah[1] << endl; cout << ah[4] << endl; Kate Gregorywith material from Deitel and Deitel

  24. Templates impose requirements • In order to work with the Array template, Holder requires: • Default constructor • operator= or single-argument constructor • operator<< • If you try to instantiate a template object and the class is missing some requirements, you’ll receive a compiler error Kate Gregorywith material from Deitel and Deitel

  25. Specialized Overrides • As with function templates, you may need to write a special case for certain types. • For example the Array template needs to initialize extra elements when it grows. It allocates a “scratch” element for this: template<class C> C& Array<C>::operator[](int i) { ... C c; ... • This only works for objects, not for fundamental types or pointers Kate Gregorywith material from Deitel and Deitel

  26. Specialized Overrides template<> int& Array<int>::operator[](int i) { . . . int c=0; . . . } Kate Gregorywith material from Deitel and Deitel

  27. Specialized Overrides template<> char*& Array<char*>::operator[](int i) { . . . char* c = ""; . . . } Kate Gregorywith material from Deitel and Deitel

  28. The Standard Template Library • Arrays, stacks, linked lists and so on are obvious template choices • Why should everyone develop them? • The Standard Template Library offers a variety of “computer science” templates that are likely to be useful in almost every program. • Most modern compilers come with an implementation of the Standard Template Library Kate Gregorywith material from Deitel and Deitel

  29. The vector STL Template #include <vector> . . . vector<int> vi; vi.push_back(1); vi.push_back(2); vi.push_back(3.5); // warning //re truncation vi.push_back(h1); //error: can't //convert Holder to int cout << vi[1] << endl; Kate Gregorywith material from Deitel and Deitel

  30. Going through the whole vector for (int i=0;i<vi.size();i++) cout << vi[i] << " " ; • What if you want them in a specific order? • What if you’re using a collection other than vector? • Not all STL collections provide operator[] access Kate Gregorywith material from Deitel and Deitel

  31. STL Iteration • The STL separates container classes (vector, stack, etc) from objects that know how to go through a container • Iterators can work with a number of different containers • An iterator “points to” each element in turn • Not really, but operator* and operator-> are overloaded Kate Gregorywith material from Deitel and Deitel

  32. Using an Iterator for (vector<int>::iterator it=vi.begin(); it != vi.end(); it++) { cout << *it << " "; } Kate Gregorywith material from Deitel and Deitel

  33. For Next class • Read chapter 14 • Lab 7 • Get ready for the final! • Thursday April 17th, 9am-noon Kate Gregorywith material from Deitel and Deitel

More Related