Получение ошибок в шаблоне класса List / Node Program

Я пытаюсь взять программу, которая создает и выполняет операции со связанным списком.

Эта программа работает и компилируется как есть, но мне нужно создать шаблонную версию программы, которая может обрабатывать данные любого типа (int, float, char). В программе есть два класса, класс NodeSLList и класс IntNode.

Я сделал все возможное, чтобы создать шаблонные версии этих двух классов, изменяя объявления и определения членов так, как мне кажется, но я не могу избавиться от некоторых из этих ошибок. Я читаю и перечитываю свои заметки о шаблонах и классах шаблонов, а также обыскиваю Интернет для лучшего объяснения, и буду продолжать работать, пока это будет опубликовано, но любая помощь в то же время мне очень нравится.

Есть два заголовочных файла и один файл исходного кода.

IntNode.h:

///////////////////////////////////////////////////////////////////////
// class IntNode
//
// Description: represents the data that we want to store in our
//              linked list
///////////////////////////////////////////////////////////////////////
#ifndef __INT_NODE__
#define __INT_NODE__

#include <iostream>

using std::ostream;// class declaration
template <typename N>
class IntNode {

// make the following friends of this class in order that they be
// able to directly access private data of this container classfriend void NodeSLList_Test(void);
template <typename N> friend class NodeSLList<N>;
friend class TSArray;
friend ostream& operator<<(ostream &, NodeSLList<N> &);

public:

///////////////////////////////////////////////////////////////////////
// ostream operator
//
// Description: provide overloaded ostream operator
// Input: reference to ostream object
//        reference to IntNode object to output
// Output: none
// Returns: reference to same ostream operator for cascading
///////////////////////////////////////////////////////////////////////
friend ostream& operator<<(ostream & out, IntNode<N> & n)
{
out << "[" << n.row << "]"<< "[" << n.col << "]"<< "[" << n.depth << "]:"<< n.data;
return out;
}///////////////////////////////////////////////////////////////////////
// default constructor
//
// Description: provide default construction of an IntNode object
// Input: row of array
//        column of array
//        depth of array
//        initial value of node
//        pointer to next IntNode
// Output: none
// Returns: reference to same ostream operator for cascading
///////////////////////////////////////////////////////////////////////
IntNode(int inRow=0, int inCol=0, int inDepth=0, N inData, IntNode<N> *in = 0)
{
data = inData;
next = in;
row = inRow;
col = inCol;
depth = inDepth;
}

///////////////////////////////////////////////////////////////////////
// GetRow
//
// Description: return row member
// Input: none
// Output: none
// Returns: row member
///////////////////////////////////////////////////////////////////////
const int GetRow() const
{
return row;
}

///////////////////////////////////////////////////////////////////////
// GetColumn
//
// Description: return column member
// Input: none
// Output: none
// Returns: column member
///////////////////////////////////////////////////////////////////////
const int GetColumn() const
{
return col;
}///////////////////////////////////////////////////////////////////////
// GetDepth
//
// Description: return depth member
// Input: none
// Output: none
// Returns: depth member
///////////////////////////////////////////////////////////////////////
const int GetDepth() const
{
return depth;
}///////////////////////////////////////////////////////////////////////
// GetData
//
// Description: return data member
// Input: none
// Output: none
// Returns: data member
///////////////////////////////////////////////////////////////////////
const N GetData() const
{
return data;
}private:

///////////////////////////////////////////////////////////////////////
// row
//
// this variable holds the row of the array element (i.e first demension)
///////////////////////////////////////////////////////////////////////
int row;

///////////////////////////////////////////////////////////////////////
// column
//
// this variable holds the column of the array element (i.e 2nd demension)
///////////////////////////////////////////////////////////////////////
int col;

///////////////////////////////////////////////////////////////////////
// depth
//
// this variable holds the column of the array element (i.e 3rd demension)
///////////////////////////////////////////////////////////////////////
int depth;

///////////////////////////////////////////////////////////////////////
// data
//
// this variable holds the actual data at the array element
///////////////////////////////////////////////////////////////////////
N data;///////////////////////////////////////////////////////////////////////
// column
//
// this variable holds the column of the array element (i.e 2nd demension)
///////////////////////////////////////////////////////////////////////
IntNode<N> *next;
};#endif __INT_NODE__

NodeSLList.h:

///////////////////////////////////////////////////////////////////////
// Class NodeSLList Interface
//
// Description - This is the interface for a class which implements
//               a singly linked list of integers. Each node in the
//               linked list is IntNode object, defined by the IntNode
//               class.
///////////////////////////////////////////////////////////////////////
#ifndef INT_LINKED_LIST
#define INT_LINKED_LIST

#include <iostream>

using std::ostream;
using std::cout;
using std::cin;
using std::endl;

#include "IntNode.h"
// Class NodeSLList Declaration

template< typename N >
class NodeSLList {///////////////////////////////////////////////////////////////////////
// operator<<
//
// Description: print the list
// Input: reference to ostream object
//        reference to an NodeSLList object to be printed
// Output: linked list printed to screen
// Returns: reference to an ostream object
///////////////////////////////////////////////////////////////////////
//friend ostream& operator<<( ostream &, NodeSLList<N> & );
template <typename N> friend ostream & operator<<(ostream &, NodeSLList<N> &);public:///////////////////////////////////////////////////////////////////////
// default constructor
//
// Description: initialize list
// Input: none
// Output: none
// Returns: none
///////////////////////////////////////////////////////////////////////
NodeSLList()
{
head = tail = 0;
}///////////////////////////////////////////////////////////////////////
// destructor
//
// Description: deallocates all memory for linked list by calling
//              destroyList() member function
// Input: none
// Output: none
// Returns: none
///////////////////////////////////////////////////////////////////////
~NodeSLList()
{
// call destroyList() to remove all nodes
// and reset linked list
DestroyList();
}///////////////////////////////////////////////////////////////////////
// IsEmpty
//
// Description: returns status of array
// Input: none
// Output: none
// Returns: TRUE if list is empty
//          FALSE otherwise
///////////////////////////////////////////////////////////////////////
bool IsEmpty() const
{
return (head == 0);
}

///////////////////////////////////////////////////////////////////////
// GetSize
//
// Description: get current number of nodes in list
// Input: none
// Output: none
// Returns: number of nodes in list
///////////////////////////////////////////////////////////////////////
int GetSize() const
{
// check to see if the list is empty. if
// so, just return 0
if ( IsEmpty() ) return 0;

int size = 1;
IntNode<N> *p = head;
// compute the number of nodes and return
while (p != tail)
{
size++;
p = p->next;
}
return size;
}

///////////////////////////////////////////////////////////////////////
// AddToHead
//
// Description: add a node to the head of the list
// Input: data for node to be added
// Output: updated linked list
// Returns: none
///////////////////////////////////////////////////////////////////////
void AddToHead(IntNode<N> & node)
{
// create a new node, and make it the head. the
// previous head will become head->next
head = new IntNode<>(node.row, node.col, node.depth, node.data, head);

// if this is the first node, make the tail the
// same as the head
if (tail == 0)
tail = head;
}

///////////////////////////////////////////////////////////////////////
// DeleteFromHead
//
// Description: remove a node from the head of the list
// Input: none
// Output: updated linked list
// Returns: data that was at the node just removed
///////////////////////////////////////////////////////////////////////
IntNode<N> DeleteFromHead()
{
IntNode<N> temp;
if (IsEmpty())
{
cout << "*****ERROR: Can't delete from head. List is Empty" << endl;
return temp;
}

temp.data = head->data;
temp.col = head->col;
temp.row = head->row;
temp.depth = head->depth;

IntNode<N> *tmp = head;

// if there is only one node, set the head and pointer tails
// to NULL (0)
if (head == tail)
head = tail = 0;

// otherwise, move the head pointer to the next node
// in the list
else
head = head->next;

// delete head node
delete tmp;

return temp;
}

///////////////////////////////////////////////////////////////////////
// DeleteFromTail
//
// Description: remove a node from the tail of the list
// Input: none
// Output: updated linked list
// Returns: data that was at the node just removed
///////////////////////////////////////////////////////////////////////
IntNode<N> DeleteFromTail()
{
IntNode<N> nodeData;
nodeData.col = tail->col;
nodeData.row = tail->row;
nodeData.depth = tail->depth;
nodeData.data = tail->data;// if there is only one node, delete the only node, and set the
// head and tail pointers to NULL (0)
if (head == tail)
{
delete head;
head = tail =0;
}

// otherwise, traverse to the tail node and delete it
else
{
IntNode<N> * temp;
for (temp = head; temp->next != tail; temp = temp->next);       //shifts thru the node, from the head to the node right before the tail
delete tail;
tail = temp;
tail->next = 0;
}

return nodeData;
}

///////////////////////////////////////////////////////////////////////
// DeleteNode
//
// Description: remove a node from the list
// Input: node number to be removed
// Output: updated linked list
// Returns: data that was at the node just removed
///////////////////////////////////////////////////////////////////////
IntNode<N> DeleteNode(int nodeNum)
{
if (nodeNum <= 0) nodeNum = 1;
IntNode<N> *prev=head , *temp=head;
IntNode<N> current;

// traverse to the node
for (int loop=1; loop<nodeNum; loop++)
{
prev=temp, temp=temp->next;
// check for case where nodeNum is > the number of
// nodes in the list. if we reach the tail before
// we traverse to the node, delete the tail
if ( temp == tail )
return DeleteFromTail();
}

// if deleting the head just call
// the appropriate member function
// and don't repeat that logic here
if (temp == head) return DeleteFromHead();

// otherwise, delete the node we traversed to
prev->next = temp->next;
current.row = temp->row;
current.col = temp->col;
current.data = temp->data;

delete temp;

return current;
}

///////////////////////////////////////////////////////////////////////
// RetrieveNode
//
// Description: retrieve data from a node without removing it from
//              the list
// Input: node number (1-N; not 0-N-1)
// Output: none
// Returns: reference to node data
///////////////////////////////////////////////////////////////////////
IntNode<N> &RetrieveNode(int nodeNum) const
{
IntNode<N> *tmp = head;

// traverse to the node, or to the last node, whichever comes
// first
for (int i=1; i< nodeNum && tmp != tail; i++)
tmp = tmp->next;

return *tmp;
}

///////////////////////////////////////////////////////////////////////
// UpdateNode
//
// Description: update a node's data
// Input: node number (1-N; not 0-(N-1))
// Output: updated node
// Returns: none
///////////////////////////////////////////////////////////////////////
void UpdateNode(int nodeNum, IntNode<N> &node)
{
IntNode<N> *tmp = head;

// traverse to the node, or to the last node, whichever comes
// first
for (int i=1; i< nodeNum && tmp != tail; i++)
tmp = tmp->next;

tmp->data = node.data;
tmp->col = node.col;
tmp->row = node.row;
}

///////////////////////////////////////////////////////////////////////
// DestroyList
//
// Description: deallocates all memory for linked list
// Input: none
// Output: reset linked list
// Returns: none
///////////////////////////////////////////////////////////////////////
void DestroyList()
{
// while the list is NOT empy
// keep removing the head node and make
// the next node the head node
for (IntNode<N> *p; !IsEmpty(); )
{
p = head->next;
delete head;
head = p;
}
head = tail = 0;
}

private:

IntNode<N> *head, *tail;

};

#endif INT_LINKED_LIST

TestDriver.cpp:

// TEST DRIVER. Only used to test the class.
// Activated by defining TEST_DRIVER in the
// Project - Settings - C/C++ - Preprocessor definitions
#ifdef LIST_DRIVER

#include <stdlib.h>
#include "NodeSLList.h"#include "IntNode.h"template <typename N>
void NodeSLList_template_Test()
{

NodeSLList_template<N> s;
IntNode_template<N> temp;

IntNode_template<N> n1(1,1,1,10);
IntNode_template<N> n2(1,2,1,20);
IntNode_template<N> n3(1,3,1,30);
IntNode_template<N> n4(1,4,1,40);
IntNode_template<N> n5(1,5,1,50);

cout << "Testing addToHead() operation" << endl;
s.AddToHead(n5);
s.AddToHead(n4);
s.AddToHead(n3);
s.AddToHead(n2);
s.AddToHead(n1);

cout << s << endl;

cout << "\nTesting GetSize() operation" << endl;
cout << "list contains " << s.GetSize() << " node(s)" << endl;

cout << "\nTesting DeleteFromHead() operation" << endl;
temp = s.DeleteFromHead();
cout << "node retrieved " << temp << endl;
cout << s << endl;

cout << "\nTesting DeleteFromTail() operation" << endl;
temp = s.DeleteFromTail();
cout << "node retrieved " << temp << endl;
cout << s << endl;

cout << "\nTesting RetrieveNode() operation" << endl;
temp = s.RetrieveNode(0);
cout << "node retrieved (should be first node) " << temp << endl;
temp = s.RetrieveNode(50);
cout << "node retrieved (should be last node) " << temp << endl;
temp = s.RetrieveNode(2);
cout << "node retrieved (should be 2nd node) " << temp << endl;
pause();

cout << "Adding n3 to head" << endl;
cout << "Adding n2 to head" << endl;
s.AddToHead(n3);
s.AddToHead(n2);
cout << "List is now: " << s << endl;
cout << "\nTesting DeleteNode() operation" << endl;
temp = s.DeleteNode(50);
cout << "node deleted (should be last node) " << temp << endl;
cout << s << endl;
temp = s.DeleteNode(3);
cout << "node deleted (should be 3rd node) " << temp << endl;
cout << s << endl;

cout << "Test SsEmpty() operation" << endl;
cout << (s.IsEmpty() ? "List IS Empty\n" : "List NOT Empty\n");

cout << "\nTesting UpdateNode() operation (updating 3rd node with [10][20][30]:500)"<< endl;
temp.row = 10;
temp.col = 20;
temp.depth = 30;
temp.data = 500;
s.UpdateNode(3,temp);
cout << s << endl;

pause();

cout << "\nTesting the ability to delete nodes from head, even" << endl
<< "after list is empty" << endl
<< "Should recieve 2 errors" << endl;
temp = s.DeleteFromHead();
temp = s.DeleteFromHead();
temp = s.DeleteFromHead();
temp = s.DeleteFromHead();
temp = s.DeleteFromHead();

cout << "\nTest IsEmpty() operation" << endl;
cout << (s.IsEmpty() ? "List IS Empty\n" : "List NOT Empty\n");

cout << "\nTesting DestroyList() operation" << endl;
s.AddToHead(n3);
s.AddToHead(n2);
s.AddToHead(n1);
cout << s << endl;
cout << "calling DestoryList()" << endl;
s.DestroyList();
cout << s << endl;

}

void pause()
{
cout << "Press RETURN to continue" << endl;
cin.get();
system("cls");
}void pause();

void main(void)
{
NodeSLList_template_Test<int>();
}#endif

И мои ошибки:

Error   1   error C2143: syntax error : missing ';' before '<' c:\cis554\hw_7_2\hw_7_2\intnode.h    24
Error   2   error C2059: syntax error : '<' c:\cis554\hw_7_2\hw_7_2\intnode.h   24
Error   3   error C2238: unexpected token(s) preceding ';'  c:\cis554\hw_7_2\hw_7_2\intnode.h   24
4   IntelliSense: default argument not at end of parameter list c:\CIS554\HW_7_2\HW_7_2\IntNode.h   61

0

Решение

У вас круговая зависимость. IntNode нужна декларация NodeSLList и наоборот.

Кроме того, имена с ведущими или двумя соседними подчеркиваниями зарезервированы для реализации, поэтому вы должны изменить это

#ifndef __INT_NODE__

что-то вроде

#ifndef INT_NODE_H_
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector