2013-02-23 71 views
0

因此,我有一個Queue類的雙向鏈表實現(請參見下文) 當我嘗試排隊時,此隊列類工作得很好整數和字符串,但由於某種原因,當我嘗試排隊一個自定義類時,我的程序絕不會移過enqueue()被調用的主線。我認爲這可能是一個無限循環,但我不確定。短小故事,爲什麼我的enqueue()方法適用於基本數據類型,如int,char,&字符串,但不適用於自定義類?嘗試將用戶定義類的實例排入隊列時無限循環(?)

這裏是我的隊列類...

// 
// queue.h 
// 
// 
// Created by Aaron Mamparo on 2/22/13. 
// 
// 

#ifndef _queue_h 
#define _queue_h 

#include <iostream> 
#include <stdio.h> 

using namespace std; 

template<class Type> 
class Node { 
public: 
    Type elem; 
    Node* next; 
    Node* prev; 
    Node() {} 
    Type Elem() { return elem; } 
    Node* Next() { return next; } 
    Node* Prev() { return prev; } 
}; 

template<class Type> 
class Queue { 
    Node<Type> *head; 
    Node<Type> *tail; 
public: 
    Queue(); 
    ~Queue(); 
    bool isEmpty(); 
    int size(); 
    void enqueue(Type); 
    Type dequeue(); 
    Node<Type>* at(int); 
    Type get(int); 
}; 

//default constructor 
template<class Type> 
Queue<Type>::Queue(){ 
    head = NULL; 
    tail = NULL; 
} 

//destructor 
template<class Type> 
Queue<Type>::~Queue(){ 
    if(!isEmpty()){ 
     while(head){ 
      Node<Type> *del = head; 
      head = head->next; 
      delete[] del; 
     } 
    } 
} 

//return true if queue is empty 
template<class Type> 
bool Queue<Type>::isEmpty(){ 
    return head == NULL; 
} 

//return number of elems in queue 
template<class Type> 
int Queue<Type>::size(){ 
    int count = 0; 
    Node<Type> *temp = head; 
    while(temp){ 
     temp = temp->next; 
     count++; 
    } 
    delete temp; 
    return count; 
} 

//insert elem to back of queue 
template<class Type> 
void Queue<Type>::enqueue(Type T){ 
    Node<Type> *newNode = new Node<Type>(); 
    newNode->elem = T; 
    newNode->next = NULL; 
    if(head==NULL){ 
     head = tail = newNode; 
     newNode->prev = NULL; 
    } else { 
     newNode->prev = tail; 
     tail->next = newNode; 
     tail = newNode; 
    } 
} 

//remove elem from front of queue 
template<class Type> 
Type Queue<Type>::dequeue(){ 
    if(isEmpty()){ 
     cerr << "Error: trying to dequeue from empty queue" << endl; 
    } else { 
     Type ret = head->Elem(); 
     Node<Type> *del = head; 
     head = head->next; 
     delete del; 
     return ret; 
    } 
} 

//return a pointer to element at position i 
template<class Type> 
Node<Type>* Queue<Type>::at(int i){ 
    if(isEmpty()){ 
     return '\0'; 
    } else if (i>size()-1){ 
     return NULL; 
    } else { 
     Node<Type> *temp = new Node<Type>(); 
     temp = head; 
     for(int j=0; j<i; j++){ 
      temp = temp->next; 
     } 
     return temp; 
    } 
} 

//remove & return element at position i 
template<class Type> 
Type Queue<Type>::get(int i){ 
    if(isEmpty()){ 
     return NULL; 
    } else if (i>size()-1){ 
     return NULL; 
    } else { 
     Node<Type> *temp = new Node<Type>(); 
     temp = head; 
     for(int j=0; j<i; j++){ 
      temp = temp->next; 
     } 
     temp->prev->next = temp->next; 
     temp->next->prev = temp->prev; 
     Type ret = temp->Elem(); 
     delete temp; 
     return ret; 
    } 
} 
#endif 

和我的主要驅動力,不會晃過stateQueue.enqueue(state);

int main() { 
    Queue<State> stateQueue; 
    State newState = readInput(); //'readInput()' returns an instance of 'State' 
    stateQueue.enqueue(newState); 

    cout << "DONE" << endl; 
    return 0; 
} 

在上面的代碼中, 「DONE」 從不顯示.. 我確定readInput()確實不是問題,因爲當我在.enqueue()呼叫之前插入「DONE」時會出現問題... 有什麼想法?

在此先感謝

編輯:這裏的默認構造函數,拷貝構造函數,析構函數和重載賦值運算符爲我State類...

State::State(){ 
    pieces = Queue<Piece>(); 
    stateHistory = Queue<string>(); 
    moveHistory = Queue<string>(); 
    rows = 0; 
    cols = 0; 
} 

//copy constructor 
State::State(const State& rhs){ 
    pieces = rhs.pieces; 
    stateHistory = rhs.stateHistory; 
    moveHistory = rhs.moveHistory; 
    rows = rhs.rows; 
    cols = rhs.cols; 
} 

//destructor 
State::~State(){ 
} 

//overloaded assignment operator 
State& State::operator=(const State &rhs){ 
    pieces = rhs.pieces; 
    stateHistory = rhs.stateHistory; 
    moveHistory = rhs.moveHistory; 
    rows = rhs.rows; 
    cols = rhs.cols; 
    return *this; 
} 

編輯:這裏有一個拷貝構造函數和重載賦值操作我只是實現...

template<class Type> 
Queue<Type>::Queue(const Queue<Type>&Q) 
{ 
    *this = Q; 
} 

template<class Type> 
Queue<Type>& Queue<Type>::operator=(const Queue<Type> &Q) 
{ 
    head = Q.head; 
    tail = Q.tail; 
    return *this; 
} 
+0

你試過調試過嗎? – 2013-02-23 17:48:48

+0

是的,我已經嘗試了多次,但無法弄清楚問題......我要再次設置一個斷點並逐步完成,以便我可以確切地告訴你它停在哪裏,給我一分鐘。 – 2013-02-23 17:50:27

+0

如果它在您嘗試使用您的自定義類時有效,那麼您的自定義類中可能存在一個缺陷。可能涉及默認構建或分配。 – 2013-02-23 17:57:25

回答

0

短的故事,總之,W我的enqueue()方法適用於基本數據類型,如int,char,&字符串,但不適用於自定義類?

這是很難肯定地說,你沒有提供State類的細節,但問題似乎是有,你有一個原始指針或東西,不實施適當的賦值運算符,您在使用隊列::排隊()方法:

newNode->elem = T; 

PS你加入國家實施(無定義雖然),但它表明,它使用Queue類本身內。狀態分配使用Queue的編譯器生成的賦值操作符,但Queue類具有原始指針,因此您可以雙重刪除頭指針。

一個可能的解決方案是將指針您的隊列裏面對象,而不是對象本身:

typedef boost::shared_ptr<State> StatePtr; 
int main() { 
    Queue<StatePtr> stateQueue; 
    StatePtr newState = readInput(); //'readInput()' now returns a smart pointer to 'State' 
    stateQueue.enqueue(newState); 

    cout << "DONE" << endl; 
    return 0; 
} 

您需要更改readInput()相應。 另外我會建議禁止複製和分配隊列對象,所以編譯器會幫助你防止這樣的問題。

+0

啊,我看到你在... ...但我怎麼解決這個問題?我很抱歉所有的問題...我是一個C++ n00b – 2013-02-23 18:30:42

+0

實現隊列 – Slava 2013-02-23 18:31:47

+0

正確的拷貝構造函數和賦值操作符好吧,我更新了原來的帖子與我實現的拷貝構造函數和賦值操作符......但它仍然將無法正常工作 – 2013-02-23 18:42:16