I have a linked list class i'd like to turn into a template so that it can handle strings,float,double,etc

I currently wrote a simple linked list class that has a node that holds the link and a string. I'd like to know practice templates. What i'd like to do is anywhere there was a string in my code i'd like to make it eneric so it can hold int,double,etc....

I'm thinking i should be able to just template the functions that handle the string parameter. Anyone who can help me learn this would be great i'll show my old code then below it i'll show how i tried to change it with comments any tips would be appreciated.

THIS IS CODE BEFORE TEMPLAE CHANGES
=================node.h========================
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

class Node
{
public:
      friend class Stack;
Node(); //default constructor
//~Node(); //destructor
string getName(Node*);
void setName(string name, Node *node); //changes a name of given node
void addNodeStart(string name);        //adds node to beginning of list
void addNodeEnd(string name);          //adds node to end of list
void deleteNode(string s);             //deletes specified node given the string
void Display();                       //displays entire list
int getSize();                         // returns size of list
Node* getPrevious(Node* current);      //returns previous node of node you specify
Node* findNode(string s);                 //finds a node given the string that node contains
//string deleteFirstNode() ;          
Node* getHead();
private:
string name;                           //name variable in node
int count;                             //count of nodes
Node *link,*head,*tail;                  
};
=======================================

===========node.cpp=============




//implementation of Node.cpp
#include <iostream>
#include <string>
#include <fstream>
#include "Node.h"
using namespace std;



/*********
Constructor
********/
Node::Node()
{
  head = NULL;
  tail=NULL;
  count=0;
 
}

/**********
Gets previous Node from current index
 ********/
Node* Node::getPrevious(Node* index)
{
  if(index == head)
  {
    return head;
  }
  else
  {
    Node* iterator;
      iterator = head;
    while(iterator->link != index)
      {
     iterator = iterator->link;  
      }
     return iterator;
  }

}

/**********
Sets the name of given node in list
 ********/
void Node::setName(string name,Node *node)
{
  node->name=name;
}

/**********
Gets name of given node
 ********/
string Node::getName(Node *node)
{
   
      return node->name;
      
}

int Node::getSize()
{
return count;
}

Node* Node::getHead()
{return head;
}

/***********
Returns:Adds node to front of list
PreCondition: If list is null it will apply this node to head of list

************/
void Node::addNodeStart(string name)
{
      
   //check make sure list is not empty
      if(head == NULL)
      {
            head = new Node;
            tail = head; //<= not sure about this
      head->name=name;
        head->link=NULL;
      
       // head = tail;  //<= and not sure about this
      }
      else
      {
        
      Node *temp_ptr;
      temp_ptr = new Node;

      temp_ptr->name=name;;

      temp_ptr->link = head;
      head = temp_ptr;
        
      }

    count++;

}

/**********
Adds new node to the end of list
 ********/
void Node::addNodeEnd(string name)
{
      
    //check make sure list is not empty
      if(head == NULL)
      {
      
        head = new Node;
        tail = head;
      head->name=name;
        head->link=NULL;
      
      }
      else
      {
        
      Node *temp_ptr;
      temp_ptr = new Node;
      temp_ptr->name=name;
        temp_ptr->link=NULL;

      tail->link=temp_ptr;
        tail= temp_ptr;
      //temp_ptr = getPrevious(tail);
     
        
      }

   count++;

}

/**********
Finds node in list given parameter string that node holds
 ********/
Node* Node::findNode(string s)
{
  Node* iterator;
  iterator= head;
  while(iterator->name != s)
  {
        iterator = iterator->link;
  }
 
  return iterator;

}

/**********
Deletes front node in the list
 ********/
void Node:: deleteNode(string s)
{

  Node* temp_ptr;
  Node* n = findNode(s);  // finds the node we want to delete
  if(n == head )
  {
    temp_ptr = head;
    head = head->link;
  delete temp_ptr;
  }
  else if( n == tail)
  {
    temp_ptr = tail;
      tail = getPrevious(tail);
      tail->link = NULL;
      delete temp_ptr;
  }
count--;

}

/*
//This is inside Node.cpp
string &Node::deleteFirstNode()
{
     if(head == NULL) return string(""); //Check for empty linked list
     string &str = head->name; //Take copy of head vlaue
     temp = head;                    //Take copy of head for delete in future
     head = head->link;            //move to the next node
     delete temp;                     //Delete temporary
     return str;
}
*/

/**********
Display the entire list
 ********/
void Node::Display()
{
  Node *iter;
cout << " the contents of the list: " << endl;
  for(iter = head; iter !=NULL; iter= iter->link)
  {
   
      cout << iter->name << " " ;
  }
  cout << endl;
  cout << "Size of linked list is: " << getSize() << endl;
}


===============================

THIS IS MY ATTEMPTS AT TEMPLATES
===============Node.h==================

nclude <iostream>
#include <string>
#include <fstream>
using namespace std;



class Node
{
public:
      friend class Stack;
Node(); //default constructor
//~Node(); //destructor
string getName(Node*);
void template<class A_Type> A_Type setName(A_Type data, Node *node); //changes a name of given node < don't understand what A_type is? why is it a class? i just
void template<class A_Type> A_Type  addNodeStart(A_Type data);        //adds node to beginning of list
void template<class A_Type> A_Type addNodeEnd(A_Type data);          //adds node to end of list
void template<class A_Type> A_Type deleteNode(A_Type data);             //deletes specified node given the string
void Display();                       //displays entire list
int getSize();                         // returns size of list
Node* getPrevious(Node* current);      //returns previous node of node you specify
Node* findNode(A_Type data);                 //finds a node given the string that node contains
//string deleteFirstNode() ;          
Node* getHead();
private:
A_Type data;                           //name variable in node
int count;                             //count of nodes
Node *link,*head,*tail;                  
};




===============================

===================node.cpp========================
//implementation of Node.cpp
#include <iostream>
#include <string>
#include <fstream>
#include "Node.h"
using namespace std;

template<class A_Type>

/*********
Constructor
********/
Node::Node()
{
  head = NULL;
  tail=NULL;
  count=0;
 
}

/**********
Gets previous Node from current index
 ********/
Node* Node::getPrevious(Node* index)
{
  if(index == head)
  {
    return head;
  }
  else
  {
    Node* iterator;
      iterator = head;
    while(iterator->link != index)
      {
     iterator = iterator->link;  
      }
     return iterator;
  }

}

/**********
Sets the name of given node in list
 ********/
void Node::setName(A_Type data,Node *node)
{
  node->data=data;
}

/**********
Gets name of given node
 ********/
string Node::getName(Node *node)
{
   
      return node->data;
      
}

int Node::getSize()
{
return count;
}

Node* Node::getHead()
{return head;
}

/***********
Returns:Adds node to front of list
PreCondition: If list is null it will apply this node to head of list

************/
void Node::addNodeStart(A_Type data)
{
      
   //check make sure list is not empty
      if(head == NULL)
      {
            head = new Node;
            tail = head; //<= not sure about this
      head->data=data;
        head->link=NULL;
      
       // head = tail;  //<= and not sure about this
      }
      else
      {
        
      Node *temp_ptr;
      temp_ptr = new Node;

      temp_ptr->data=data;

      temp_ptr->link = head;
      head = temp_ptr;
        
      }

    count++;

}

/**********
Adds new node to the end of list
 ********/
void Node::addNodeEnd(A_Type data)
{
      
    //check make sure list is not empty
      if(head == NULL)
      {
      
        head = new Node;
        tail = head;
      head->data=data;
        head->link=NULL;
      
      }
      else
      {
        
      Node *temp_ptr;
      temp_ptr = new Node;
      temp_ptr->data=data;
        temp_ptr->link=NULL;

      tail->link=temp_ptr;
        tail= temp_ptr;
      //temp_ptr = getPrevious(tail);
     
        
      }

   count++;

}

/**********
Finds node in list given parameter string that node holds
 ********/
Node* Node::findNode(A_Type data)
{
  Node* iterator;
  iterator= head;
  while(iterator->data != data)//<=== not sure if this will always test ok?
  {
        iterator = iterator->link;
  }
 
  return iterator;

}

/**********
Deletes front node in the list
 ********/
void Node:: deleteNode(A_Type s)
{

  Node* temp_ptr;
  Node* n = findNode(s);  // finds the node we want to delete
  if(n == head )
  {
    temp_ptr = head;
    head = head->link;
  delete temp_ptr;
  }
  else if( n == tail)
  {
    temp_ptr = tail;
      tail = getPrevious(tail);
      tail->link = NULL;
      delete temp_ptr;
  }
count--;

}

/*
//This is inside Node.cpp
string &Node::deleteFirstNode()
{
     if(head == NULL) return string(""); //Check for empty linked list
     string &str = head->name; //Take copy of head vlaue
     temp = head;                    //Take copy of head for delete in future
     head = head->link;            //move to the next node
     delete temp;                     //Delete temporary
     return str;
}
*/

/**********
Display the entire list
 ********/
void Node::Display()
{
  Node *iter;
cout << " the contents of the list: " << endl;
  for(iter = head; iter !=NULL; iter= iter->link)
  {
   
      cout << iter->name << " " ;
  }
  cout << endl;
  cout << "Size of linked list is: " << getSize() << endl;
}

350 points the last of my points to those that can help me better understand how this works!2





==================================================
tyweed420Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

FismanCommented:
Why not use the standard template library !

The STL is included in almost all C++ compilers and includes <vector>, <list> and <map> which may be of use.
boycyCommented:
Ok you're on the right track but your syntax is incorrect. I won't post a full corrected solution - it is better for you to correct the code yourself. Here is how templating syntax works:

In the header/interface (.h) file, you declare the class, and define it as a template. From your code listing above for Node.h, this would be a corrected version:

// ==================== Node.h >
template<class A_Type>
class Node
{
   public:
        friend class Stack;
   Node(); //default constructor
   //~Node(); //destructor
   string getName(Node*);
   void setName(A_Type data, Node *node);   //  <==== problem line
// ==================== Node.h <

I understand your difficulties; some of the syntax can be a little confusing. The keyword 'class' in template<class A_Type> does not mean class in the usual C++ terminology. A better keyword which performs the exact same function is 'typename'. From MSDN, the following two definitions are identical:
   template< class T1, class T2 > class X...
   template< typename T1, typename T2 > class X...

'A_Type' can be whatever you want it to be. It is the name, or placeholder, for the type upon which you are templating. You state that your class has a single templated type parameter, which you will call A_Type. Whenever A_Type is referred to, it means the type the user chose when instantiating it (creating an instance of the template class based on a specific type). It could be called anything, T is quite common.


In your implementation, just as you have to state which class member functions belong to by scoping them, eg. Node::Node(), so you must state the template and type parameters, like this:

// ==================== Node.cpp >
template<class A_Type>
Node<A_Type>::Node()
{
  head = NULL;
  tail=NULL;
  count=0;

}

// ...

template<class A_Type>
Node<A_Type>* Node<A_Type>::findNode(A_Type data)
{
  Node* iterator;
  iterator= head;
  while(iterator->data != data)//<=== not sure if this will always test ok?
  {
       iterator = iterator->link;
  }

  return iterator;

}

// ==================== Node.cpp <

Then, wherever in your implementation you say 'A_Type' (or whatever you called it), you are referring to the type the user chose. Here's an example:

Node<int> intNode;
// Create an instance of your templated class. Every 'A_Type' reference will be an int for that object.

Node<string> intNode;
// This one creates a node which can hold strings, i.e. your initial untemplated. implementation.

Hope that helps, let me know if you need any more. Templates can be tricky to grasp at first.
--Rob
tyweed420Author Commented:
I'm still confused. I don't understand i was assuming i'd only have to issue the template syntax for the functions that need the template characteristics? I have a few questions if you don't mind

1. in the header file i'm a bit confused what you say to do. I understand  


template <class A_Type> <= i understand this part
class Node
{
public:
      friend class Stack;
Node(); //default constructor
//~Node(); //destructor
string getName(Node*);

void setName(A_Type data, Node *node);  <== you said there is a problem here so
void template<A_Type>::setName(A_Type data, Node *node);<== do i need to define scope here? it just seems i'd do that in .cpp..is that what i need to do in node.h

void addNodeStart(A_Type data);      <== so here because i'm using A_Type i need to define template
void addNodeEnd(A_Type data);        <== here
void deleteNode(A_Type data);             <==here
void Display();                      
int getSize();                        
Node* getPrevious(Node* current);  
Node* findNode(A_Type data);        <========so here too        
//string deleteFirstNode() ;          
Node* getHead();
private:
A_Type data;                           //name variable in node
int count;                             //count of nodes
Node *link,*head,*tail;                  
};

and as for the node.cpp
========================




template<class A_Type>

/*********
Constructor
********/
Node<A_Type>::Node()<===== <A_type> here gets no errors but.............. look at next function
{
  head = NULL;
  tail=NULL;
  count=0;
 
}

/**********
Gets previous Node from current index
 ********/
Node<A_Type>* Node<A_Type>::getPrevious(Node* index)  <========= but here i get error with just <A_Type> ??
{
  if(index == head)
  {
    return head;
  }
  else
  {
    Node* iterator;
      iterator = head;
    while(iterator->link != index)
      {
     iterator = iterator->link;  
      }
     return iterator;
  }

}

/**********
Sets the name of given node in list
 ********/
void Node::setName(A_Type data,Node *node)
{
  node->data=data;
}

/**********
Gets name of given node
 ********/
string Node::getName(Node *node)
{
   
      return node->data;
      
}

int Node::getSize()
{
return count;
}

Node* Node::getHead()
{return head;
}

/***********
Returns:Adds node to front of list
PreCondition: If list is null it will apply this node to head of list

************/
void Node::addNodeStart(A_Type data)
{
      
   //check make sure list is not empty
      if(head == NULL)
      {
            head = new Node;
            tail = head; //<= not sure about this
      head->data=data;
        head->link=NULL;
      
       // head = tail;  //<= and not sure about this
      }
      else
      {
        
      Node *temp_ptr;
      temp_ptr = new Node;

      temp_ptr->data=data;

      temp_ptr->link = head;
      head = temp_ptr;
        
      }

    count++;

}

/**********
Adds new node to the end of list
 ********/
void Node::addNodeEnd(A_Type data)
{
      
    //check make sure list is not empty
      if(head == NULL)
      {
      
        head = new Node;
        tail = head;
      head->data=data;
        head->link=NULL;
      
      }
      else
      {
        
      Node *temp_ptr;
      temp_ptr = new Node;
      temp_ptr->data=data;
        temp_ptr->link=NULL;

      tail->link=temp_ptr;
        tail= temp_ptr;
      //temp_ptr = getPrevious(tail);
     
        
      }

   count++;

}

/**********
Finds node in list given parameter string that node holds
 ********/
Node* Node::findNode(A_Type data)
{
  Node* iterator;
  iterator= head;
  while(iterator->data != data)//<=== not sure if this will always test ok?
  {
        iterator = iterator->link;
  }
 
  return iterator;

}

/**********
Deletes front node in the list
 ********/
void Node:: deleteNode(A_Type s)
{

  Node* temp_ptr;
  Node* n = findNode(s);  // finds the node we want to delete
  if(n == head )
  {
    temp_ptr = head;
    head = head->link;
  delete temp_ptr;
  }
  else if( n == tail)
  {
    temp_ptr = tail;
      tail = getPrevious(tail);
      tail->link = NULL;
      delete temp_ptr;
  }
count--;

}

/*
//This is inside Node.cpp
string &Node::deleteFirstNode()
{
     if(head == NULL) return string(""); //Check for empty linked list
     string &str = head->name; //Take copy of head vlaue
     temp = head;                    //Take copy of head for delete in future
     head = head->link;            //move to the next node
     delete temp;                     //Delete temporary
     return str;
}
*/

/**********
Display the entire list
 ********/
void Node::Display()
{
  Node *iter;
cout << " the contents of the list: " << endl;
  for(iter = head; iter !=NULL; iter= iter->link)
  {
   
      cout << iter->name << " " ;
  }
  cout << endl;
  cout << "Size of linked list is: " << getSize() << endl;
}




boycyCommented:
Ok, one thing unclear in the way most if not all people lay out template code is that they split the definition onto two lines. The part in Node.h conceptually reads:

template<class A_Type> class Node { // ... };

This defines Node as a template class with one type parameter called 'A_Type'. Everything within the braces defining class Node is a part of that template.
Now, in the implementation file, where you would usually have to specify e.g. void Node::Display(), because it is templated, you must now write

template<class A_Type> void Node<A_Type>::Display()

As well as having to specify that Display() is a member function of Node by scoping: Node::Display(), you must also restate that the function is part of a templated class, that way you may then refer to the type parameter A_Type by name.

I hope that helps, if not I will rephrase. If you need to post any more code snippets, please try to cut them down to the relevant parts; it's difficult to trawl through screenfuls of code to find a particular comment.
--Rob

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.