1 linked lists iii template chapter 3. 2 objectives you will be able to: write a generic list class...

Post on 30-Mar-2015

216 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1

Linked Lists IIITemplate

Chapter 3

2

Objectives

You will be able to: Write a generic list class as a C++

template. Use the template in a test program.

3

Issues in the int List Class

The list can only hold integers.

Solution: Make it a template.

4

Templates

Templates are a feature in C++ that permit code to be more reusable.

They have blanks, called parameters, that can be automatically filled in with type names at compile time.

Rather than having to define separate classes for lists of ints, doubles, Circles, Dogs, Cats, etc., we can define a single List template.

A user of the template can supply the name of the class that will be the data in list nodes.

The compiler handles the substitution of the class name specified by the user for the parameter into the template definition.

Result is a List class specialized for the user’s class.

5

Limitations of Template

A class used as a template parameter must meet certain requirements.

Must implement all operators used by the template methods. Typically

= (Assignment operator) Copy constructor

6

Templates

We have two kinds of templates in C++. Function templates. Class templates.

In each, parameters can be specified for one or more types. The parameters are used as if they were real

type names.

The compiler substitutes real type names, specified by the user, for the parameters when the template is used.

7

C++ Templates

The word template is a C++ keyword

In front of a function definition, it specifies that what follows is … a pattern for a function definition not a real function definition.

Type parameters appear within angle brackets ( < > ) before the function definition.

Normal function parameters appear within parentheses, as in normal function definitions.

8

Caution

A function template cannot be split across files. Specification and implementation must be in

the same file. Just a .h file. No .cpp file.

9

A Function Template

template <class T> T is a parameter

void Swap (T &first, T &second)

{

T temp = first;

first = second;

second = temp;

}

The keyword typename can be used instead of the keyword class in the first line.

10

Function Template Instantiation

When the compiler encounters a call to a function defined as a template, it generates a real function definition substituting the type(s) of the function arguments for the template parameter(s).

The function call looks exactly like a call to a normally defined function.

Example: swap (a[i], a[i+1]);

11

Class Templates

We can define templates for classes as well as for functions.

Specify one or more template parameters in front of the class definition.

The class definition uses the parameters as if they were real class names.

Real class names must be provided as values for the parameters whenever the template is used.

12

General Form Of Class Template Declaration

template <class TypeParam1, class TypeParam2,..., class TypeParamN>class SomeClass{ // ... members of SomeClass ...};

Within the class definition, the class parameters TypeParam1, TypeParam2, … TypeparamN can be used as if they were real class names.

The parameter names can be any valid C++ name. (Same rules as for variable names.)

When the class is used, real class names will be provided and substituted for the parameters.

class is a C++ keyword here.

13

Alternative Form

Keyword typename can be used instead of

keyword class in the template parameter list.

template <typename TypeParam1, typename TypeParam2,..., typename TypeParamN>class SomeClass{ // ... members of SomeClass ...};

14

Instantiating Class Templates

Instantiate the template by writing a declaration of form

SomeClass<Type> objectName;

where “Type” represents a real class name and SomeClass is the name of the template class.

Passes Type as an argument to the class definition template.

Examples: Stack<int> intStack;Stack<string> stringStack;

Compiler will generate two distinct definitions of Stack Two instances of the class definition One for ints and one for strings.

15

Rules For Class Templates

1. Member functions outside the class declaration must be function templates.

2. Member functions must be defined in the same file as the class declaration.

3. All uses of the template class name as a type must be parameterized.

16

Convert intDLList into a List Template

Create a new project. List_Template_Demo

Copy the files from intDLList2 into the project directory.

http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_01_24_Doubly_Linked_List_2/

Add the .h file to the project. Rename as DLList.h

17

Convert intDLList into a List Template

Modify the existing code for intDLList to make it a template.

Have to copy the function definitions from the .cpp file into the .h file.

Replace int by a class parameter.

Replace class names by new parameterized class names.

18

The Node Class Definition

//************************ DLList.h *****************// Doubly-linked list template

#ifndef DLLIST_H#define DLLIST_H

template<class T>class DLLNode {public: T info; DLLNode<T> *next; DLLNode<T> *prev;

DLLNode(T el, DLLNode<T> *ptr1 = 0, DLLNode<T> *ptr2 = 0) { info = el; next = ptr1; prev = ptr2; }};

19

Problem with the Listhead

In the intDLList we create the Listhead with an info value of 0. The value is never used.

We can't do this with a template. For an arbitrary class, T, 0 might not be

a valid value. We need a constructor for class

DLLNode that doesn't specify a value for info.

Leaves info uninitialized in the Listhead.

20

Default Constructor for DLLNode

Add to DLLNode class defintion:

DLLNode()

{

next = 0;

prev = 0;

}

21

DLList Class Definition

template<class T>

class DLList

{

private:

DLLNode<T>* ListHead;

public:

DLList()

{

ListHead = new DLLNode<T>();

ListHead->next = ListHead;

ListHead->prev = ListHead;

}

22

DLList Class Definition

DLList(const DLList<T>& original);

DLList& operator=(const DLList<T>& original);

~DLList();

int isEmpty() const

{

return ListHead->next == ListHead;

}

void addToHead(const T&);

void addToTail(const T&);

T deleteFromHead(); // Delete the head and return its info;

T deleteFromTail(); // Delete the tail and return its info;

void deleteNode(const T&);

bool isInList(const T&) const;

void printAll() const;

};

23

Destructor

template<class T>DLList<T>::~DLList(void){ while (!isEmpty()) { DLLNode<T> *p = ListHead->next->next; delete ListHead->next; ListHead->next = p; }}

24

addToHead

template<class T>void DLList<T>::addToHead(const T& el) { DLLNode<T> *p = new DLLNode<T>(el);

p->next = ListHead->next; p->prev = ListHead;

ListHead->next->prev = p; ListHead->next = p;}

25

addToTail

template<class T>void DLList<T>::addToTail(const T& el) { DLLNode<T> *p = new DLLNode<T>(el);

p->next = ListHead; p->prev = ListHead->prev;

ListHead->prev->next = p; ListHead->prev = p;}

26

deleteFromHead

template<class T>T DLList<T>::deleteFromHead() { if (isEmpty()) { throw("Attempt to delete from empty list"); } T el = ListHead->next->info;

DLLNode<T> *tmp = ListHead->next; ListHead->next->next->prev = ListHead; ListHead->next = ListHead->next->next;

delete tmp; return el;}

27

deleteFromTail

template<class T>T DLList<T>::deleteFromTail() { if (isEmpty()) { throw("Attempt to delete from empty list"); } T el = ListHead->prev->info;

DLLNode<T> *tmp = ListHead->prev; ListHead->prev->prev->next = ListHead; ListHead->prev = ListHead->prev->prev;

delete tmp; return el;}

28

deleteNode

template<class T>void DLList<T>::deleteNode(const T& el) { DLLNode<T> *p = ListHead->next; while (p != ListHead && p->info != el) { p = p->next; }

if (p == ListHead) { return; // It's not there. Claim success! }

// p points to node to be deleted. p->prev->next = p->next; p->next->prev = p->prev; delete p;}

29

isInList

template<class T>bool DLList<T>::isInList(const T& el) const { DLLNode<T> *p = ListHead->next; while (p != ListHead && p->info != el) { p = p->next; }

return p != ListHead;}

30

printAll

template<class T>void DLList<T>::printAll() const {

if (isEmpty())

{

cout << "List is empty\n";

return;

}

DLLNode<T> *p = ListHead->next; while (p != ListHead) { cout << p->info << endl; p = p->next; }

cout << endl;}

31

Copy Constructor

// Copy constructor

template<class T>

DLList<T>::DLList(const DLList<T>& original)

{

ListHead = new DLLNode<T>();

ListHead->next = ListHead;

ListHead->prev = ListHead;

// Copy the original list

DLLNode* p = original.ListHead->next;

while (p != original.ListHead)

{

addToTail(p->info);

p = p->next;

}

}

32

Assignment Operator

// Assignment operator

template<class T>

DLList<T>& DLList<T>::operator=(const DLList<T>& original)

{

if (this == &original) // Check for self assignment

{

return *this;

}

while (!isEmpty()) // Delete the current list contents

{

deleteFromTail();

}

delete ListHead;

33

Assignment Operator

ListHead = new DLLNode<T>();

ListHead->next = ListHead;

ListHead->prev = ListHead;

// Copy the original list

DLLNode<T>* p = original.ListHead->next;

while (p != original.ListHead)

{

addToTail(p->info);

p = p->next;

}

return *this;

}

34

Testing the Template

Adapt the test driver for intDLList to use the DLList template.

Parmeterize the template for int. Results should be identical to

previous.

35

main.cpp

#include <iostream>

#include "DLList.h"

using namespace std;

int main()

{

DLList<int> myList;

...

myList = new DLList<int>();

...

myList = new DLList<int>();

...

Everything else is unchanged.

36

Program Running

top related