2012-11-21 25 views
0

我正在嘗試創建一個程序並在鏈接列表上執行操作。在模板類中獲取錯誤列表/節點程序

此程序按原樣工作並編譯,但我必須創建可處理任何類型數據(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 class 


    friend 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 

回答

1

你有循環依賴。 IntNode需要NodeSLList的聲明,反之亦然。

順便說一句,與領先的下劃線或兩個相鄰的下劃線的名字被保留用於執行,所以你應該改變這種

#ifndef __INT_NODE__ 

喜歡的東西

#ifndef INT_NODE_H_