Class Templates Computer Science Dept Va Tech January






























- Slides: 30
Class Templates Computer Science Dept Va Tech January 2000 Templates OO Software Design and Construction 1 © 2000 Mc. Quain WD
Motivation for Templates 2 You want both: – – a list of Location objects a list of Maze. Monster objects How can you accomplish this by writing one Linked. List class? – – state all the ways you can think of doing this state the pros/cons of each method Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
One Way to Look at Templates. . . Templates 3 Until now, we have used variables: – – The type of a variable is fixed when you write code. The value of a variable isn’t fixed when you write code. With templates, type isn’t fixed when you write code! With templates, you use a type more or less as a variable! Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Example: Queue of some type Foo Templates 4 C++ keywords template <class Foo> class Queue { Parameter, can be any type private: Foo buffer[100]; int head, tail, count; public: Queue(); void Insert(Foo item); Foo Remove(); ~Queue(); }; Computer Science Dept Va Tech January 2000 OO Software Design and Construction The header of a templated class declaration specifies one or more type names which are then used within the template declaration. These type names are typically NOT standard or user-defined types, but merely placeholder names that serve as formal parameters. © 2000 Mc. Quain WD
C++ Templates 5 Definition of “template”: Parameterized class with parameters that denote unknown types. Usage: In situations where the same algorithms and/or data structures need to be applied to different data types. Declaration syntax: template <class Foo> class Queue { // template member declarations go here }; Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
What can a parameter be used for? Templates 6 To specify the type specifying of data which will be local to objects of the class: private: Foo buffer[100]; To specify the type of a parameter to a class member function: void Insert(Foo item); To specify the return type of a class member function: Foo Remove(); Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Instantiating a Templates 7 Given the template declaration: template <class Foo> class Queue {. . . }; Instantiate Queue of ints in 2 ways: – Queue<Location> int. Queue; – typedef Queue<int> Integer. Queue; Integer. Queue int. Queue; Both of these define an object int. Queue. Note how an actual type (Location or int) is substituted for the template parameter (Foo) in the object declaration. Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Usage of Templates 8 Once created, the template object is used like any other object: int. Queue. Insert(100); int. Queue. Insert(200); // add 100 to the queue // add 200 The parameter type for the member function Insert() was specified as Foo in the template declaration and mapped to int in the declaration of the object int. Queue. When calling Insert() we supply an int value. int x = int. Queue. Remove(); // remove 100 int. Queue. Insert(300); // queue now // has (200, 300) int Sz = int. Queue. Size(); // size is 2 Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Compiler view of templates. . . Templates 9 The compiler macro expands the template code: – – – You write Queue<int> int. Queue. Compiler emits new copy of a class named “Queueint” and substitutes <int> for <Foo> throughout. Therefore, the compiler must have access to the implementation of the template member functions in order to carry out the substitution. Therefore, the template implementation CANNOT be pre-compiled. Most commonly, all template code goes in the header file with the template declaration. The compiler “maps” the declaration: private: Foo buffer[100]; to the declaration: Computer Science Dept Va Tech January 2000 The compiler “mangles” the template name with the actual parameter (type name) to produce a unique name for the class. private: Queueint buffer[100]; OO Software Design and Construction © 2000 Mc. Quain WD
Implementing Template Class Methods template and actual parameter(s) Class name and actual parameter(s) Templates 10 Scope resolution operator and function name template<class Foo> Queue<Foo>: : Queue() { //. . . member function body goes here } Return type goes here: template<class Foo> void Queue<Foo>: : Insert(Foo item) { //. . . member function body goes here } Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
A Complete Templated Class Templates 11 // Queue. T. h #ifndef QUEUET_H #define QUEUET_H #include <cassert> const int Size = 100; template <class Foo> class Queue. T { private: Foo buffer[Size]; int Head, Tail, Count; public: Queue. T(); void Enqueue(Foo Item); Using the template Foo Dequeue(); parameter: data type, int get. Size() const; parameter type, return bool is. Empty() const; type. bool is. Full() const; ~Queue. T(); }; //. . . template implementation goes here #endif Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
A Complete Template Class Templates 12 //. . . continuing header file Queue. T. h template <class Foo> Queue. T<Foo>: : Queue. T() : Head(0), Tail(0), Count(0) { } template <class Foo> void Queue. T<Foo>: : Enqueue(Foo Item) { assert(Count < Size); // die if Queue is full! buffer[Tail] = Item; Tail = (Tail + 1) % Size; // circular array indexing Count++; } Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
A Complete Template Class Templates 13 //. . . continuing header file Queue. T. h template <class Foo> Foo Queue. T<Foo>: : Dequeue() { assert(Count > 0); // die if Queue is empty int old. Head = Head; // remember where old Head was Head = (Head + 1) % Size; // reset Head Count--; return buffer[old. Head]; // return old Head } template <class Foo> int Queue. T<Foo>: : get. Size() const { return (Count); } Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
A Complete Template Class Templates 14 //. . . continuing header file Queue. T. h template <class Foo> bool Queue. T<Foo>: : is. Empty() const { return (Count == 0); } template <class Foo> bool Queue. T<Foo>: : is. Full() const { return (Count < Size - 1); } template <class Foo> Queue. T<Foo>: : ~Queue. T() { } //. . . end template Queue. T<Foo> implementation Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
A Driver for the Queue. T Templates 15 #include <iostream> #include <iomanip> using namespace std; #include "Queue. T. h" void main() { const int num. Vals = 10; Queue. T<int> int. Q; for (int i = 0; i < num. Vals; i++) { int. Q. Enqueue(i*i); } 0 1 2 3 4 5 6 7 8 9 0 1 4 9 16 25 36 49 64 81 int Limit = int. Q. get. Size(); for (i = 0; i < Limit; i++) { int next. Val = int. Q. Dequeue(); cout << setw(3) << i << setw(5) << next. Val << endl; } } Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Recap Templates 16 Note that method bodies use the same algorithms for a queue of ints or a queue of doubles or a queue of Locations… But the compiler still type checks! It does a macro expansion, so if you declare Queue. T<int> i. Queue; Queue. T<char> c. Queue; Queue. T<Location> Vertices; the compiler has three different classes after expansion to use with normal type checking rules. Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Implicit Assumptions in Queue. T Templates 17 Declaration of the array of Foos assumes Foo has a default constructor: template <class Foo> class Queue { private: Foo buffer[Size]; . . . }; Assignment of Foos assumes Foo has appropriately overloaded the assignment operator: template <class Foo> void Queue<Foo> : : Insert(Foo item) {. . . buffer[tail] = item; . . . }; Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Implicit Assumptions in Queue. T Templates 18 The way that Foos are returned by Remove() method assumes Foo has provided an appropriate copy constructor: template <class Foo> Foo Queue<Foo>: : Remove() {. . . return buffer[val]; } Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Variable and Constant Template Parameters Templates 19 Template parameters may be: type names (we saw this previously) variables e. g. , to specify a size for a data structure constants useful to define templates for special cases Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Queue Template with a Variable Parameter Templates 20 One weakness of the Queue. T template is that the queue array is of a fixed size. We can easily make that user-selectable: template <class Foo, int Size> class Queue. T { private: Foo buffer[Size]; int Head, Second template parameter is Tail; just an int variable, which int Count; falls within the class scope public: Queue. T(); just as a private data member bool Enqueue(Foo Item); would. bool Dequeue(Foo& Item); int get. Size() const; bool is. Empty() const; bool is. Full() const; ~Queue. T(); }; Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Driver for Revised Queue Template #include <iostream> #include <iomanip> using namespace std; #include "old. Queue. T. h" void main() { const int small. Size = 10; const int large. Size = 100; Templates 21 The value specified in the declaration must still be a constant though. . . Queue. T<int, small. Size> small. Q; Queue. T<int, large. Size> large. Q; for (int i = 0; i < small. Size-1; i++) small. Q. Enqueue(i); for (i = 0; i < large. Size-1; i++) { large. Q. Enqueue(i); for (i = 0; i < small. Size-1; i++) { int next. Val; large. Q. Dequeue(next. Val); cout << setw(3) << i << setw(5) << next. Val << endl; } } Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Template Type-checking Templates 22 Suppose we have the declarations: Queue. T<int, 100> Queue. T<int, 1000> Queue. T<float, 1000> small. Integer. Queue; large. Integer. Queue 2; small. Real. Queue; large. Real. Queue; Which (if any) of the following are legal assignments: small. Integer. Queue = large. Integer. Queue; small. Integet. Queue = small. Real. Queue; large. Integer. Queue = large. Integer. Queue 2; Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Constant Parameter Templates 23 Sometimes we need to handle a special case: class Displayable<int> { private: int does not define int Displayed; ostream* Out; to. String or from. String string to. String(int Value); int from. String(string Text); public: Displayable(ostream* o); // output stream to show in void Show. This(int d); // what to show void Show(); // show current value void Reset(); // reset value from stdin ~Displayable(); }; Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Special Case Displayable Templates 24 string Displayable<int>: : to. String(int Value) { string Buffer; ostringstream Format(Buffer); Format << Value; return Buffer; } int Displayable<int>: : from. String(string Text) { istringstream Format(Text); int Value; Format >> Value; return Value; } Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Linked List Templates 25 template <class Base. Type> class List { private: . . . public: List(); void First(); void Next(); int Done(); Base. Type& Current(); void Insert(Base. Type val); void Delete(); ~List(); }; Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
The Node Templates 26 template <class Base. Type> class Node { private: Base. Type value; Node<Base. Type> *next; public: Node(Base. Type base); Base. Type& Value(); void Connect. To(Node<Base. Type>* nxt); Node<Base. Type>* Next(); ~Node(); }; Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Implementation of the Node Templates 27 template <class Base. Type> Node<Base. Type>: : Node(Base. Type base) : value(base), next(0) {} template <class Base. Type> Base. Type& Node<Base. Type>: : Value() { return value; } template <class Base. Type> void Node<Base. Type>: : Connect. To(Node<Base. Type>* nxt) { next = nxt; } template <class Base. Type> Node<Base. Type>* Node<Base. Type>: : Next() { return next; } Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Relationship of the List and Node Templates template <class Base. Type> class private: Node<Base. Type> *head; // Node<Base. Type> *current; // Node<Base. Type> *previous; // // public: // shown above }; Computer Science Dept Va Tech January 2000 Templates 28 List { beginning of list current element previous element; needed for deletion OO Software Design and Construction © 2000 Mc. Quain WD
Implementation of List Insert Templates 29 template <class Base. Type> void List<Base. Type>: : Insert(Base. Type val) { Node<Base. Type> *new. Node = new Node<Base. Type> (val); if (head == NULL) { head = current = new. Node; return; } assert(current != NULL); new. Node->Connect. To(current->Next()); current->Connect. To(new. Node); current = new. Node; } Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD
Implementation of Delete Templates 30 template <class Base. Type> void List<Base. Type>: : Delete() { assert(current != NULL); Node<Base. Type> *temp = current; if (current == head) { head = head->Next(); current = head; delete temp; return; } assert(previous != NULL); current = current->Next(); previous->Connect. To(current); delete temp; } Computer Science Dept Va Tech January 2000 OO Software Design and Construction © 2000 Mc. Quain WD