2014-03-02 69 views
-1

我正在編寫我的編程類,我們必須編寫雙鏈表,然後將其轉換爲模板雙鏈表。我得到了非模板版本的工作,但現在我無法弄清楚如何解決我的錯誤在模板版本。我會先把代碼放在這裏,然後討論下面的錯誤。雙鏈表列表模板錯誤(C++)

TemplateDoublyLinkedList.h

#include <cstdlib> 
#include <iostream> 
using namespace std; 
template <typename T> 
class DoublyLinkedList; // class declaration 

// list node 
template <typename T> 
class DListNode { 
private: T obj; 
    DListNode *prev, *next; 
    friend class DoublyLinkedList<T>; 
public: 
    DListNode(T object = T(), DListNode *p = NULL, DListNode *n = NULL) 
    : obj(object), prev(p), next(n) {} 
    T getElem() const { return obj; } 
    DListNode * getNext() const { return next; } 
    DListNode * getPrev() const { return prev; } 
}; 

// doubly linked list 
template <typename T> 
class DoublyLinkedList { 
protected: DListNode header, trailer; 
public: 
    DoublyLinkedList() : header(0), trailer(0) // constructor 
    { /*header.next = &trailer; trailer.prev = &header;*/ } 
    DoublyLinkedList(const DoublyLinkedList<T>& dll); // copy constructor 
    ~DoublyLinkedList(); // destructor 
    DoublyLinkedList& operator=(const DoublyLinkedList<T>& dll); // assignment operator 
    // return the pointer to the first node 
    DListNode *getFirst() const { return header.next; } 
    // return the pointer to the trailer 
    const DListNode *getAfterLast() const { return &trailer; } 
    // return if the list is empty 
    bool isEmpty() const { return header.next == &trailer; } 
    T first() const; // return the first object 
    T last() const; // return the last object 
    void insertFirst(T newobj); // insert to the first of the list 
    T removeFirst(); // remove the first node 
    void insertLast(T newobj); // insert to the last of the list 
    T removeLast(); // remove the last node 
}; 
// output operator 
template <typename T> 
ostream& operator<<(ostream& out, const DoublyLinkedList<T>& dll); 

// extend range_error from <stdexcept> 
template <typename T> 
struct EmptyDLinkedListException : std::range_error { 
    explicit EmptyDLinkedListException(char const* msg=NULL): range_error(msg) {} 
}; 

// copy constructor 
template <typename T> 
DoublyLinkedList<T>::DoublyLinkedList(const DoublyLinkedList<T>& dll) 
{ 
    header.next = &trailer; trailer.prev = &header; 

    DListNode<T>* current = dll.getFirst(); 
    while (current != dll.getAfterLast()) { 
     T newObj = current->obj; 
     insertLast(newObj); 
     current = current->getNext(); 
    } 

} 
// assignment operator 
template <typename T> 
DoublyLinkedList<T>& DoublyLinkedList<T>::operator=(const DoublyLinkedList<T>& dll) 
{ 
    delete this; 

    header.next = &trailer; trailer.prev = &header; 

    DListNode<T>* current = dll.getFirst(); 
    while (current != dll.getAfterLast()) { 
     T newObj = current->obj; 
     insertLast(newObj); 
     current = current->getNext(); 
    } 

    return *this; 
} 
// insert the object to the first of the linked list 
template <typename T> 
void DoublyLinkedList<T>::insertFirst(T newobj) 
{ 
    DListNode<T> *newNode = new DListNode(newobj, &header, header.next); 
    header.next->prev = newNode; 
    header.next = newNode; 
} 
// insert the object to the last of the linked list 
template <typename T> 
void DoublyLinkedList<T>::insertLast(T newobj) 
{ 
    DListNode<T> *newNode = new DListNode(newobj, trailer.prev,&trailer); 
    trailer.prev->next = newNode; 
    trailer.prev = newNode; 
} 
// remove the first object of the list 
template <typename T> 
T DoublyLinkedList<T>::removeFirst() 
{ 
    if (isEmpty()) 
    throw EmptyDLinkedListException("Empty Doubly Linked List"); 
    DListNode<T> *node = header.next; 
    node->next->prev = &header; 
    header.next = node->next; 
    T obj = node->obj; 
    delete node; 
    return obj; 
} 
// remove the last object of the list 
template <typename T> 
T DoublyLinkedList<T>::removeLast() 
{ 
    if (isEmpty()) 
    throw EmptyDLinkedListException("Empty Doubly Linked List"); 
    DListNode<T> *node = trailer.prev; 
    node->prev->next = &trailer; 
    trailer.prev = node->prev; 
    T obj = node->obj; 
    delete node; 
    return obj; 
} 
// destructor 
template <typename T> 
DoublyLinkedList<T>::~DoublyLinkedList() 
{ 
    DListNode<T> *prev_node, *node = header.next; 
    while (node != &trailer) { 
    prev_node = node; 
    node = node->next; 
    delete prev_node; 
    } 
    header.next = &trailer; 
    trailer.prev = &header; 
} 
// return the first object 
template <typename T> 
T DoublyLinkedList<T>::first() const 
{ 
    if (isEmpty()) 
    throw EmptyDLinkedListException("Empty Doubly Linked List"); 
    return header.next->obj; 
} 
// return the last object 
template <typename T> 
T DoublyLinkedList<T>::last() const 
{ 
    if (isEmpty()) 
    throw EmptyDLinkedListException("Empty Doubly Linked List"); 
    return trailer.prev->obj; 
} 
// return the list length 
template <typename T> 
T DoublyLinkedListLength(DoublyLinkedList<T>& dll) { 
    DListNode<T> *current = dll.getFirst(); 
    int count = 0; 
    while(current != dll.getAfterLast()) { 
    count++; 
    current = current->getNext(); //iterate 
    } 
    return count; 
} 
// output operator 
template <typename T> 
ostream& operator<<(ostream& out, const DoublyLinkedList<T>& dll) { 
    DListNode<T> *current = dll.getFirst(); 
    while (current != dll.getAfterLast()) { 
     out << current->getElem() << '\n'; 
     current = current->getNext(); 
    } 
    return out; 
} 

TemplateMain.cpp

#include "TemplateDoublyLinkedList.h" 
#include <iostream> 
#include <string> 
#include <cstdio> 
#include <sstream> 
using namespace std; 
int main() { 
    // Construct a linked list with header & trailer 
    cout << "Create a new list" << endl; 
    DoublyLinkedList<string> dll; 
    cout << "list: " << dll << endl << endl; 

    // Insert 10 nodes at back with value 10,20,30,..,100 
    cout << "Insert 10 nodes at back with value 10,20,30,..,100" << endl; 
    for (int i=10;i<=100;i+=10) { 
    stringstream ss; 
    ss << i; 
    dll.insertLast(ss.str()); 
    } 
    cout << "list: " << dll << endl << endl; 

    // Insert 10 nodes at front with value 10,20,30,..,100 
    cout << "Insert 10 nodes at front with value 10,20,30,..,100" << endl; 
    for (int i=10;i<=100;i+=10) { 
    stringstream ss; 
    ss << i; 
    dll.insertFirst(ss.str()); 
    } 
    cout << "list: " << dll << endl << endl; 

    // Copy to a new list 
    cout << "Copy to a new list" << endl; 
    DoublyLinkedList<string> dll2(dll); 
    cout << "list2: " << dll2 << endl << endl; 

    // Assign to another new list 
    cout << "Assign to another new list" << endl; 
    DoublyLinkedList<string> dll3=dll; 
    cout << "list3: " << dll3 << endl << endl; 

    // Delete the last 10 nodes 
    cout << "Delete the last 10 nodes" << endl; 
    for (int i=0;i<10;i++) { 
    dll.removeLast(); 
    } 
    cout << "list: " << dll << endl << endl; 

    // Delete the first 10 nodes 
    cout << "Delete the first 10 nodes" << endl; 
    for (int i=0;i<10;i++) { 
    dll.removeFirst(); 
    } 
    cout << "list: " << dll << endl << endl; 

    // Check the other two lists 
    cout << "Make sure the other two lists are not affected." << endl; 
    cout << "list2: " << dll2 << endl; 
    cout << "list3: " << dll3 << endl; 

    return 0; 
} 

現在它列出一堆錯誤,但是所有錯誤中的一個共同主題是,它說(在概要):「當編譯類模板成員函數'DoublyLinkedList :: DoublyLinkedList(const DoublyLinkedList &)'with T = std :: string「

所以我認爲這意味着我的模板有一個錯誤,它不接受字符串進入模板,但不知道如何解決它。謝謝你的幫助。

編輯:我想我修復了所有位置,如 DListNode * current = dll.getFirst();

但我仍然得到了一些錯誤,例如在它認爲使用類模板的第24行需要模板參數列表

+1

如何修復這些類型的錯誤:*錯誤:使用類模板'DListNode'需要模板參數:'DListNode * current = dll.getFirst();'*(其中約有10個) – dyp

+0

將''放置在我看到DListNode的每個位置?這是我很困惑的一部分 – user3369628

+0

修復這些錯誤後,它編譯。但是,引發了一個'logic_error'異常(即代碼中可能存在錯誤)。 – dyp

回答

0

我沒有看,通過你的所有的類定義,但即使DoublyLinkedList的第一個構造函數無效

DoublyLinkedList() : header(0), trailer(0) // constructor 
    { header.next = &trailer; trailer.prev = &header; } 

如果首部和尾部由初始化爲零則既assignmnets

header.next = &trailer; trailer.prev = &header; 

可導致異常結束的程序。

此外,他們沒有任何意義。構造函數應該沒有這些任務

DoublyLinkedList() : header(0), trailer(0) {} 

而且您的定義有其他錯誤是簡單的。例如,而不是

DListNode* current = dll.getFirst(); 

應該有

DListNode<T>* current = dll.getFirst(); 

因爲類DListNode是一個模板類。

此外,它是一個不好的清單設計。類DListNode應該是DoublyLinkedList的內部類。將它與Double DouedList類分開定義是沒有意義的。此外,如果DoublyLinkedList是DListNode的朋友類,那麼不清楚爲什麼getNext和getPrev方法被定義。

+0

那部分代碼我沒有寫,但是作爲教授的源代碼給了我。在我寫作自己的作品時,我會在將來徵求你的意見,但在這種情況下,這不是我寫的,所以不能成爲我錯誤的根源。 – user3369628

+0

@ user3369628編寫代碼的人並不重要。該代碼必須是有效的。否則,沒有意義使用它。 –

+0

我發佈了我上面編輯的代碼,但它仍然無法正常工作,儘管我的錯誤比以前少了很多。還修復構造函數沒有減少或添加到我的錯誤。 – user3369628