·       Templates – Allow you to define functions and classes that have parameters for type names.

o      Function Templates

§       Syntax – The function declarations and definitions should begin with a template prefix which tells the compiler that the declaration or function that follows is a template and that ‘T’ is the type parameter.

 

//Example

template<class T>

int someFunction(T var1);

 

§       The compiler behaves as if it produces all definitions for the types used for T.  When the compiler gets the function call, it notices the types of arguments, and then uses the template to produce a function definition of the type parameter T replaced with the argument type.

§       Some Functions may require more than one parameter type.  To do this, you add the types in the template prefix, function declaration and function definition.

 

//Example

template<class T1, class T2>

int someFunction(T1 var1, T1 var2, T2 var3);

 

§       Note:  Some compilers do not allow separate compilation of templates, so you may need to include the template definition with the code that uses it (i.e., directly or using a #include).

§       Note: the word “class” in the template prefix is a throwback to the early days of templates.  ANSI/ISO changes this word to “typename” (which is a better name that matches what the intention is).  However, “class” is used almost exclusively in the real world.  Recommendation – use the word “class” instead of “typename”.

o      class Templates

§       Syntax – Precede the class definition with a template prefix which tells the compiler that the class is a template class of type T.

 

//Example

template<class T>

class SomeClass

{

public:

          SomeClass();

          SomeClass(T var1, T var2);

          etc...

};

 

§       Function definitions of the class should each have a template prefix as well.

 

//Example

template<class T>

int someFunction(T var1);

 

o      Detailed Example – The following example uses templates to create multiple linked lists from multiple data files and allow for changes to be made (and saved) to each type of linked list.  The use of templates simplifies the code by allowing us to use types as parameters, thus minimizing the need for duplicate code to keep track of multiple linked lists.

 

// Example

#include <iostream>

#include <string>

#include <fstream>

 

using namespace std;

 

// Person Class and Implmentation

class Person

{

public:

       Person(string fName, string lName, int age)

              : _fName(fName), _lName(lName), _age(age) {}

       ~Person() {}

 

       void setFirstName(string fName) { _fName = fName; }

       string getFirstName() const { return _fName; }

 

       void setLastName(string lName) { _lName = lName; }

       string getLastName() const { return _lName; }

 

       void setAge(int age) { _age = age; }

       int getAge() const { return _age; }

 

       bool matchTarget(string lName) const;

       void display() const;

 

private:

       string _fName;

       string _lName;

       int _age;

};

 

bool Person::matchTarget(string lName) const

{

       return (_lName == lName);

}

 

void Person::display() const

{

       cout << "\n*****************************************************\n";

       cout << "Name: " << getFirstName() << " " << getLastName() << endl;

       cout << "Age:  " << getAge() << endl;

       cout << "\n*****************************************************\n";

}

 

 

 

// Pet Class and Implmentation

class Pet

{

public:

       Pet(string petName, string petType, string petBreed, int age)

              : _petName(petName), _petType(petType),

                _petBreed(petBreed), _age(age) {}

       ~Pet() {}

 

       void setPetName(string petName) { _petName = petName; }

       string getPetName() const { return _petName; }

 

       void setPetType(string petType) { _petType = petType; }

       string getPetType() const { return _petType; }

 

       void setPetBreed(string petBreed) { _petBreed = petBreed; }

       string getPetBreed() const { return _petBreed; }

 

       void setAge(int age) { _age = age; }

       int getAge() const { return _age; }

 

       bool matchTarget(string lName) const;

       void display() const;

 

private:

       string _petName;

       string _petType;

       string _petBreed;

       int _age;

};

 

bool Pet::matchTarget(string petName) const

{

       return (_petName == petName);

}

 

void Pet::display() const

{

       cout << "\n*****************************************************\n";

       cout << "Name:  " << getPetName() << endl;

       cout << "Type:  " << getPetType() << endl;

       cout << "Breed: " << getPetBreed() << endl;

       cout << "Age:   " << getAge() << endl;

       cout << "\n*****************************************************\n";

}

 

 

// Node Class definition and In-line Implementations.

template<class T>

class Node

{

public:

       Node() { _data = NULL; _link = NULL; }

       Node(T* data, Node<T>* link) : _data(data), _link(link) {}

       ~Node() { if(_data) delete _data; }

 

       void setData(const T* data) { _data = data; }

       T* getData() const { return _data; }

 

       void setLink(Node <T>* ptr) { _link = ptr;}

       Node<T>* getLink() const { return _link; }

 

private:

       T *_data;

       Node<T>* _link;

};

 

 

// Function for inserting node at head of list

template<class T>

void headInsert(T* data, Node<T>*& head)

{

       head = new Node<T>(data, head);

}

 

 

 

// Function for deleting node at head of list

template<class T>

void headDelete(Node<T>*& head)

{

       Node<T>* pDiscard = head;

 

       head = head->getLink();

       delete pDiscard;

}

 

// Function for inserting in the middle or end of the list

template<class T>

void insertNode(const T* data, Node<T>* pPutAfterMe)

{

       pPutAfterMe->setLink(new Node<T>(data, pPutAfterMe->getLink()));

}

 

// Function for deleting in the middle or end of the list

template<class T>

void discardNode(Node<T>* pDiscardMe, Node<T>*& head)

{

       if(pDiscardMe == head)

       {

              headDelete(head);

              return;

       }

 

       Node<T>* pBeforeNode = head;

 

       while( (pBeforeNode->getLink() != pDiscardMe) &&

(pBeforeNode->getLink() != NULL))

              pBeforeNode = pBeforeNode->getLink();

 

       if(pBeforeNode->getLink() == NULL)

       {

              cout << "\nCannot find node to discard.\n";

              return;

       }

 

       pBeforeNode->setLink(pDiscardMe->getLink());

       delete pDiscardMe;

}

 

// Function to search through the linked list

template<class T, class T2>

Node<T>* search(Node<T>* found, const T2 target)

{

       if(found == NULL) // Empty list case

       {

              cout << "\n*****************************************************\n";

              cout << "The list is currently empty.";

              cout << "\n*****************************************************\n";

              return NULL;

       }

 

       while(!(found->getData()->matchTarget(target)) &&

(found->getLink() != NULL))

              found = found->getLink();

 

       if(found->getData()->matchTarget(target))

              return found;

       else

       {

              cout << "\n*****************************************************\n";

              cout << "Item Not found.";

              cout << "\n*****************************************************\n";

              return NULL;

       }

}

 

// Function to display one person of the linked list

template<class T>

void displayNode(Node<T>* current)

{

       if(current == NULL) // Empty list case

       {

              cout << "\n*****************************************************\n";

              cout << "The list is currently empty.";

              cout << "\n*****************************************************\n";

              return;

       }

 

       current->getData()->display();

}

 

// Function to display the current contents of the linked list

template<class T>

void displayList(Node<T>* current)

{

       if(current == NULL) // Empty list case

       {

              cout << "\n*****************************************************\n";

              cout << "The list is currently empty.";

              cout << "\n*****************************************************\n";

              return;

       }

 

       do

       {

              current->getData()->display();

 

              current = current->getLink();

       } while (current != NULL);

}

 

template<class T>

void deleteList(Node<T>*& head)

{

       if(head == NULL)

              return;

 

       Node<T>* current = NULL;

 

       while(head != NULL)

       {

              current = head->getLink();

              delete head;

              head = current;

       }

}

 

 

 

 

 

 

template<class T1, class T2>

int getLinkedLists(Node<T1>*& personList, Node<T2>*& petList)

{

       ifstream inFile1, inFile2;

       int age;

 

       // Person Variables

       Person *pPerson;

       string lastName, firstName;

 

       // Pet Variables

       Pet *pPet;

       string petName, petType, petBreed;

      

       // Open the People data file to read in the People linked list

       inFile1.open("people.txt");

       if(inFile1.fail())

       {

              cout << "\nWarning: Could not open the People data file for reading.\n";

       }

 

       // Read into the linked list from the People data file

       while((inFile1 >> firstName) && (inFile1 >> lastName) &&

(inFile1 >> age))

       {

              pPerson = new Person(firstName, lastName, age);

              headInsert(pPerson, personList);

       }

 

       inFile1.close();

 

       // Open the Pet data file to read in the Pet linked list

       inFile2.open("pet.txt");

       if(inFile2.fail())

       {

              cout << "\nWarning: Could not open the Pet data file for reading.\n";

       }

 

       // Read into the linked list from the Pet data file

       while((inFile2 >> petName)  && (inFile2 >> petType) &&

              (inFile2 >> petBreed) && (inFile2 >> age))

       {

              pPet = new Pet(petName, petType, petBreed, age);

              headInsert(pPet, petList);

       }

 

       inFile2.close();

 

       return 0;

}

 

template<class T1, class T2>

void saveLinkedLists(Node<T1>* personList, Node<T2>* petList)

{

       ofstream outFile1, outFile2;

 

       // Open the People data file to write out the linked list

       outFile1.open("people.txt");

       if(outFile1.fail())

       {

              cout << "\nCould not open the People data file for writing.\n";

              return;

       }

 

       if(personList == NULL)

       {

              cout << "\nWriting an empty list.\n";

              outFile1.close();  // Makes an empty list

              return;

       }

 

       // Write the linked list to the data file

       while(personList != NULL)

       {

              outFile1 << personList->getData()->getFirstName() << " ";

              outFile1 << personList->getData()->getLastName() << endl;

              outFile1 << personList->getData()->getAge() << endl;

 

              personList = personList->getLink();

       }

 

       outFile1.close();

 

       // Open the Pet data file to write out the linked list

       outFile2.open("pet.txt");

       if(outFile2.fail())

       {

              cout << "\nCould not open the Pet data file for writing.\n";

              return;

       }

 

       if(petList == NULL)

       {

              cout << "\nWriting an empty list.\n";

              outFile2.close();  // Makes an empty list

              return;

       }

 

       // Write the linked list to the data file

       while(petList != NULL)

       {

              outFile2 << petList->getData()->getPetName() << endl;

              outFile2 << petList->getData()->getPetType() << endl;

              outFile2 << petList->getData()->getPetBreed() << endl;

              outFile2 << petList->getData()->getAge() << endl;

 

              petList = petList->getLink();

       }

 

       outFile2.close();

 

       return;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

int main()

{

       // Person variables

       Node<Person> * pPersonStart = NULL;

       Node<Person> * pPersonCurrent = NULL;

       Person* pPerson = NULL;

       string lastName, firstName;

 

       // Pet variables

       Node<Pet> * pPetStart = NULL;

       Node<Pet> * pPetCurrent = NULL;

       Pet* pPet = NULL;

       string petName, petType, petBreed;

      

       // General variables

       int age;

       int choice, choice2;

 

       if(getLinkedLists(pPersonStart, pPetStart))

              return 1;

 

       do

       {

              do

              {

                     cout << "\n\nThe ABC People and Pet Registry\n\n";

                     cout << "1= Person, 2= Pet, 5= Quit\n\n";

                     cout << "Choice> ";

                     cin >> choice;

              } while ((choice < 1) || (choice > 5) || (choice == 3) || (choice == 4));

 

              if(choice == 5)

              {

                     saveLinkedLists(pPersonStart, pPetStart);

                     deleteList(pPersonStart);

                     deleteList(pPetStart);

                     return 1;

              }

 

              do

              {

                     cout << "1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit\n\n";

                     cout << "Choice> ";

                     cin >> choice2;

              } while ((choice2 < 1) || (choice2 > 5));

 

              switch(choice)

              {

              case 1:

                     switch(choice2)

                     {

                     case 1:

                           cout << "Last Name: ";

                           cin >> lastName;

                           cout << "First Name: ";

                           cin >> firstName;

                           cout << "Age: ";

                           cin >> age;

 

                           pPerson = new Person(firstName, lastName, age);

                           headInsert(pPerson, pPersonStart);

                           break;

 

                     case 2:

                           cout << "Last Name: ";

                           cin >> lastName;

 

                           pPersonCurrent = search(pPersonStart, lastName);

                           if(pPersonCurrent)

                                  discardNode(pPersonCurrent, pPersonStart);

                           break;

 

                     case 3:

                           cout << "Last Name: ";

                           cin >> lastName;

 

                           pPersonCurrent = search(pPersonStart, lastName);

                           if(pPersonCurrent)

                                  displayNode(pPersonCurrent);

                           break;

 

                     case 4:

                           displayList(pPersonStart);

                           break;

 

                     case 5:

                           saveLinkedLists(pPersonStart, pPetStart);

                           deleteList(pPersonStart);

                           deleteList(pPetStart);

                           return 0;

                            break;

                     }

                     break;

 

              case 2:

                     switch(choice2)

                     {

                     case 1:

                           cout << "Pet Name: ";

                           cin >> petName;

                           cout << "Pet Type: ";

                           cin >> petType;

                           cout << "Pet Breed: ";

                           cin >> petBreed;

                           cout << "Age: ";

                           cin >> age;

 

                           pPet = new Pet(petName, petType, petBreed, age);

                           headInsert(pPet, pPetStart);

                           break;

 

                     case 2:

                           cout << "Pet Name: ";

                           cin >> petName;

 

                           pPetCurrent = search(pPetStart, petName);

                           if(pPetCurrent)

                                  discardNode(pPetCurrent, pPetStart);

                           break;

 

                     case 3:

                           cout << "Pet Name: ";

                           cin >> petName;

 

                           pPetCurrent = search(pPetStart, petName);

                           if(pPetCurrent)

                                  displayNode(pPetCurrent);

                           break;

 

                     case 4:

                           displayList(pPetStart);

                           break;

 

                     case 5:

                           saveLinkedLists(pPersonStart, pPetStart);

                           deleteList(pPersonStart);

                           deleteList(pPetStart);

                           return 0;

                           break;

                     }

                     break;

              }

 

       } while (1);

 

       saveLinkedLists(pPersonStart, pPetStart);

       deleteList(pPersonStart);

       deleteList(pPetStart);

       return 0;

}

 

 

// Sample Output #1

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 1

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 4

 

*****************************************************

Name: John Doe

Age:  50

 

*****************************************************

 

*****************************************************

Name: Paul Collins

Age:  37

 

*****************************************************

 

*****************************************************

Name: Grace Williams

Age:  26

 

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 2

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 4

 

*****************************************************

The list is currently empty.

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 1

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 3

Last Name: Collins

 

*****************************************************

Name: Paul Collins

Age:  37

 

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 2

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 1

Pet Name: Spot

Pet Type: Dog

Pet Breed: Mixed

Age: 10

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 2

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 1

Pet Name: Mittens

Pet Type: Cat

Pet Breed: Mixed

Age: 6

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 2

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 4

 

*****************************************************

Name:  Mittens

Type:  Cat

Breed: Mixed

Age:   6

 

*****************************************************

 

*****************************************************

Name:  Spot

Type:  Dog

Breed: Mixed

Age:   10

 

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 2

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 3

Pet Name: Spot

 

*****************************************************

Name:  Spot

Type:  Dog

Breed: Mixed

Age:   10

 

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 2

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 2

Pet Name: Mittens

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 2

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 4

 

*****************************************************

Name:  Spot

Type:  Dog

Breed: Mixed

Age:   10

 

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 1

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 3

Last Name: Collins

 

*****************************************************

Name: Paul Collins

Age:  37

 

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 1

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 2

Last Name: Collins

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 1

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 4

 

*****************************************************

Name: John Doe

Age:  50

 

*****************************************************

 

*****************************************************

Name: Grace Williams

Age:  26

 

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 2

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 4

 

*****************************************************

Name:  Spot

Type:  Dog

Breed: Mixed

Age:   10

 

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 5

Press any key to continue

 

 

 

 

// Sample Output #2.  I restarted the program and listed the pets and people.

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 1

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 4

 

*****************************************************

Name: Grace Williams

Age:  26

 

*****************************************************

 

*****************************************************

Name: John Doe

Age:  50

 

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 2

1= Add, 2= Delete, 3= Find, 4= Display List, 5= Quit

 

Choice> 4

 

*****************************************************

Name:  Spot

Type:  Dog

Breed: Mixed

Age:   10

 

*****************************************************

 

 

The ABC People and Pet Registry

 

1= Person, 2= Pet, 5= Quit

 

Choice> 5

Press any key to continue

 

 

 

 

·       Standard Template Library – Not covered in this class, but read Chapter 19 for pertinent information on the STL.

 

Hosted by www.Geocities.ws

1