Ch71 Chapter 7 Templates. Ch72 Motivation for Templates zYou want a ylist of shapes ylist of frames...

Post on 21-Jan-2016

212 views 0 download

Transcript of Ch71 Chapter 7 Templates. Ch72 Motivation for Templates zYou want a ylist of shapes ylist of frames...

Ch7 1

Chapter 7

Templates

Ch7 2

Motivation for Templates

You want a list of shapes list of frames

How can you write one list class? List all ways you can think of List pros/cons of each method

Ch7 3

One Way to Look at Templates...

Until now, we used variables. The type of vars is fixed when you write code. The value of vars isn’t fixed when you write code.

With templates, type isn’t fixed when you write code!

You can sort of use a type as a variable!

Ch7 4

Template Example:Queue of some type blah

template <class BlahBlah> class Queue {

private:BlahBlah buffer[100];int head, tail, count;

public:Queue();void Insert(BlahBlah item);BlahBlah Remove();~Queue();

};

Parameter, can be any type

KeywordsKeywordsEither a class or method definition

starts here.

Ch7 5

Templates

Definition of “template”:Parameterized class with parameters.Parameters denote unknown type.

Usage:Situations where same algorithms & data

structures are applied to different data types

Syntax Example:template <class BlahBlah> class Queue {...}

Ch7 6

What can a Parameter be used for?

1. as type of local data to class:private:

BlahBlah buffer[100];

2. as method argument type:void Insert(BlahBlah item);

3. as method return type:BlahBlah Remove();

Ch7 7

Instantiating a template

Given:template <class BlahBlah> class Queue {...}

Instantiate Queue of ints in 2 ways:

Queue<int> intQueue;

typedef Queue<int> IntegerQueue; IntegerQueue intQueue;

Both of these define an object intQueue.Both of these define an object intQueue.

Ch7 8

Usage of Templates

intQueue.Insert(100); // add 100intQueue.Insert(200); // add 200int x = intQueue.Remove(); // remove 100intQueue.Insert(300); // queue now // has (200,300)int x = intQueue.Size(); // size is 2

Ch7 9

Compiler view of templates...

Compiler macro expands template code: You write Queue<int> intQueue; Compiler emits new copy of a class named

“Queueint” & substitutes <int> for <blahblah>

Therefore, all template code goes in a header file

Soprivate:

BlahBlah buffer[100];becomes

private:Queueint buffer[100];

Ch7 10

Syntax for Implementing Template Class Methods

template<class BlahBlah> Queue<BlahBlah> ::Queue() { ... }

template<class BlahBlah> void Queue<BlahBlah>::Insert(BlahBlah item)

{ ... }template<class BlahBlah> BlahBlah Queue<BlahBlah>::Remove() { ... }template<class BlahBlah> int

Queue<BlahBlah>::Size() { ... }template<class BlahBlah> Queue<BlahBlah>::~Queue() { ... }

return type

Ch7 11

A Complete Template Class

template <class BlahBlah> class Queue { private: BlahBlah buffer[100]; int head, tail, count; public:

Queue(); void Insert(BlahBlah item); BlahBlah Remove(); int Size(); ~Queue();};

Using the templateparameter: arg type,

ret type, data.

All template codegoes in a header file

Ch7 12

A Complete Template Class (Continued)

template <class BlahBlah> Queue<BlahBlah>::Queue():count(0), head(0), tail(0)

{}

template<class BlahBlah> voidQueue<BlahBlah>::Insert(BlahBlah item) {

assert(count <100);buffer[tail] = item;

tail = (tail + 1)% 100; count++;}

header file

Ch7 13

A Complete Template Class (Continued)

template <class BlahBlah> BlahBlah Queue<BlahBlah>::Remove() {

assert(count > 0);int val = head;head = (head + 1)%100;count--;return buffer[val];

}template <class BlahBlah> int

Queue<BlahBlah>::Size() {return count;}

template <class BlahBlah>Queue<BlahBlah> ::~Queue() {}

header file

Ch7 14

Recap

Note that method bodies… Use same algorithm for queue of ints,

Shapes, … But compiler still type checks!

(It does macro expansion, so if you declareQueue<int>

Queue<char>

compiler has two different classes after expansion to use with normal type checking rules.)

Ch7 15

3 Implicit Assumptions on Template Parameters: QueueExample

1. Declaration of the array of BlahBlahs:Assumes BlahBlah has no-args constructortemplate <class BlahBlah> class Queue {

private: BlahBlah buffer[100];

... };2. Assignment of BlahBlahs:

Assumes BlahBlah has appropriately assignment operator.template <class BlahBlah> void

Queue<BlahBlah> ::Insert(BlahBlah item){ ...

buffer[tail] = item;...

};

Ch7 16

3 Implicit Assumptions on Template Parameters: QueueExample (Contd.)

3. The way that BlahBlahs are returned by Remove method:Assumes BlahBlah has appropriate copy constructor.

template <class BlahBlah> BlahBlahQueue<BlahBlah>::Remove(){...return buffer[val];

}

Ch7 17

Morale:

Have fun decoding those compiler error messages!

Ch7 18

More complex template...

Template “Displayable” Points to a TextBox Knows how to set TextBox to a string Knows how to retrieve value from

TextBox Want template arg to be class

(OctalNumber, int, …)

Section 7.2

Ch7 19

The Displayable Template

template <class T> class Displayable { private:

T* displayed;TextBox* textBox;

public:Displayable(TextBox* tbox); void ShowThis(T* d); void Show(); void Reset(); ~Displayable();

};

Ch7 20

Implementation of the Displayable Template

template <class T> Displayable<T>::Displayable(TextBox *tbox) {textBox = tbox; displayed = (T*)0;}

template <class T> Displayable<T>::ShowThis(T* d) { displayed = d; }

template <class T> Displayable<T>::Show() { textBox->SetText(displayed ->ToString()); }

template <class T> Displayable<T>::Reset(T* d) { displayed->FromString() (textBox->GetText()); }

Assumption: T has ToString(), FromString methods

Ch7 21

Variable and Constant Template Parameters

Template parameters may be Classes

we saw this previously

VariablesE.g., to specify a size for a data structure

ConstantsUseful to define templates for special cases

Section 7.3

Ch7 22

Queue Template Class Queue Template Class with a Variable Parameterwith a Variable Parameter

template <class BlahBlah, int size> class Queue {

private: BlahBlah buffer[size]; int head, tail, count;

public: Queue(); void Insert(BlahBlah item); BlahBlah Remove(); int Size(); ~Queue();

};

Ch7 23

Usage of Template Class Usage of Template Class with a Variable Parameterwith a Variable Parameter

Queue<int,100> smallIntegerQueue; Queue<int, 1000> largeIntegerQueue; Queue<int, 1000> largeIntegerQueue2; Queue<float, 100> smallRealQueue; Queue<float, 1000> largeRealQueue;

smallIntegerQueue = largeIntegerQueue;

smallIntegetQueue = smallRealQueue;

largeIntegerQueue = largeIntegerQueue2;

Are theselegal?

Ch7 24

Constant ParameterConstant Parameter

class Displayable<int> { private: int* displayed; TextBox* textBox; char* ToString(int v); int FromString(char* text); public: Displayable(TextBox* tbox); // textbox to show in void ShowThis(int* d); // what to show void Show(); // show current value void Reset(); // reset value from // textBox ~Displayable(); };

int does not defineToString or FromString

Special cases are sometimes desired

Ch7 25

Special Case Displayable Template Special Case Displayable Template

(Continued)(Continued)

char* Displayable<int>::ToString(int v) { char* buf = new char[10]; ostrstream format(buf); format << v; return buf;}

int Displayable<int>::FromString(char* text) { istrstream(text) format; int value; format >> value; return value; }

Ch7 26

Partial Definition of the List Template: Partial Definition of the List Template: A Related Templates ExampleA Related Templates Example

template <class BaseType> class List { private: ... public: List(); void First(); void Next(); int Done(); BaseType& Current(); void Insert(BaseType val); void Delete(); ~List(); };

Section 7.4

Ch7 27

The Node TemplateThe Node Template

template <class BaseType> class Node { private: BaseType value; Node<BaseType> *next;

public: Node(BaseType base); BaseType& Value(); void ConnectTo(Node<BaseType>* nxt); Node<BaseType>* Next(); ~Node();};

Ch7 28

Implementation of the Node TemplateImplementation of the Node Template

template <class BaseType> Node<BaseType>::Node(BaseType base) :value(base), next(0) {}

template <class BaseType> BaseType& Node<BaseType>::Value(){return value;}

template <class BaseType> void Node<BaseType>::ConnectTo(Node<BaseType>* nxt) {next = nxt; }

template <class BaseType> Node<BaseType>* Node<BaseType>::Next() {return next; }

template <class BaseType> Node<BaseType>::~Node(){}

Ch7 29

Relationship Between the List and Node Relationship Between the List and Node TemplatesTemplates

template <class BaseType> class List {

private: Node<BaseType> *head; // beginning of list Node<BaseType> *current; // current element Node<BaseType> *previous; // previous element; // needed for deletion public:

... // shown above};

Ch7 30

Implementation of InsertImplementation of Insert

template <class BaseType> void List<BaseType>::Insert(BaseType val) { Node<BaseType> *newNode = new Node <BaseType> (val); if (!head) { head = current = newNode; return; } assert(current); newNode->ConnectTo(current->Next()); current->ConnectTo(newNode); current = newNode; }

Ch7 31

Implementation of DeleteImplementation of Delete

template <class BaseType> void List<BaseType>::Delete() { assert(current); Node<BaseType> *temp = current; if(current == head) { head = head->Next(); current = head; delete temp; return; } assert(previous); current = current->Next(); previous->ConnectTo(current); delete temp;}

Ch7 32

Templates and Inheritance

Template may inherit from TemplateNon-template may inherit from

TemplateTemplate may inherit from non-

templateTemplates may use multiple

inheritence

Section 7.5

Ch7 33

Inheritance Between Inheritance Between TemplatesTemplates

template <class BlahBlah> class Queue {

private: BlahBlah buffer[100]; int head, tail, count;

public: Queue(); void Insert(BlahBlah item); BlahBlah Remove(); ~Queue();

};

Ch7 34

Inheritance Between Inheritance Between Templates (cont’d)Templates (cont’d)

template <class BlahBlah> class InspectableQueue : public Queue<BlahBlah>{ public: InspectableQueue(); BlahBlah Inspect(); // return without removing the //first element ~InspectableQueue();};

Base class is elaborated with same

parameterized type

Ch7 35

Using InspectableQueue Using InspectableQueue TemplateTemplate

InspectableQueue<Location> locations;Location loc1(...);Location loc2(...); ...locations.Insert(loc1); // base class methodlocations.Insert(loc2); // base class method ...Location front = locations.Remove(); // base class methodLocation newFront = locations.Inspect(); // derived class // method

Ch7 36

NonTemplate Inheriting NonTemplate Inheriting from Templatefrom Template

template <class BaseType> class List { private: ... public: List(); void First(); void Next(); int Done(); BaseType& Current(); void Insert(BaseType val); void Delete(); ~List();};

Ch7 37

Polygon Class Inherits from Polygon Class Inherits from List TemplateList Template

class Polygon : public List<Location> // Polygon "is-a" list of Locations{ public: Polygon(); void Draw(Canvas& canvas); // draw itself};

Base class is elaborated with a

specific type

Ch7 38

Using Polygon ClassUsing Polygon Class

Polygon poly; ...poly.Insert(Location(20,20)); // inherited from templatepoly.Insert(Location(30,30)); // inherited from template

// insert other locations

poly.Draw(canvas); // derived class method

Ch7 39

The Sequenced Interface and the Clock Class

class SequencedInterface{ public: virtual void Show() = 0; virtual void Next() = 0;};

Ch7 40

The Sequenced Interface and the Clock Class (Contd.)

class Clock{ private:

SequencedInerface *sequenced; public:

Clock() {}void ConnectTo(SequencedInterface& sq)

{ sequenced = &sq;}void ConnectTo(SequencedInterface* sq){ sequenced = sq;}void Notify() { sequenced->Next();

sequenced->Show(); }};

Ch7 41

Defining the ImplementsSequenced Template by Inheritance from a Non-Template Class

template class <SequencedImplementation> class Sequenced : public SequencedInterface { private:

SequencedImplementation& seqItem; public: Sequenced(SequencedImplementation& item) : seqItem(item) {}

void Next() { seqItem.Next();} void Show() { seqItem.Show();}};

Ch7 42

Usage of the ImplementsSequenced Template

Clock timer;

Counter time(0); ...Sequenced <Counter> timedCounter(time); ...timer.ConnectTo( (SequencedInterface&)timedCounter ); ..timer.Notify(); // invokes Next and Show in time object

Ch7 43

Templates Using Multiple Inheritance

template class <SequencedImplementation> class Sequenced : public SequencedInterface { private: SequencedImplementation& seqItem; public: Sequenced(SequencedImplementation& item) :

seqItem(item) {} void Next() { seqItem.Next();} void Show() { seqItem.Show();}

};

Ch7 44

Templates Using Multiple Inheritance (Contd.)

template class <SequencedImplementation> class SequencedObject

: public SequencedImplementation,public SequencedInterface

{ public:

SequencedObject(SequencedImplementation& item) :SequencedImplementation(item) {}void Next() { SequencedImplementation::Next();}void Show() { SequencedImplementation::Show();}

};

Ch7 45

Using the Sequenced and SequencedObject Templates

Clock timer;Counter time(0); ...Sequenced <Counter> timedCounter(time); ...timer.ConnectTo((SequencedInterface&)timedCounter ); ...timer.Notify();

Clock timer;Counter time(0);...SequencedObject <Counter> timedCounter(time);...timer.ConnectTo((SequencedInterface&)timedCounter );...timer.Notify();