尝试将用户定义类的实例排入队列时出现无限循环(?)



所以我有一个Queue类的双链表实现(见下文)当我尝试将int和字符串排队时,这个队列类工作得很好,但由于某种原因,当我尝试对自定义类排队时,我的程序永远不会超过在main中调用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 '';
    } 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"时会打印出来。。。有什么想法吗?

提前感谢

EDIT:这是我的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;
}

简而言之,为什么我的enqueue()方法适用于int、char和&字符串,但不适用于自定义类?

很难确定,因为您没有提供State类的详细信息,但问题似乎存在,您有一个原始指针或其他东西,并且没有实现正确的赋值运算符,您在Queue::enqueue()方法:中使用该运算符

newNode->elem = T;

PS您添加了State实现(但不是定义),但它表明它在内部使用了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()。此外,我建议禁止复制和分配Queue对象,这样编译器可以帮助您防止类似的问题。

相关内容

  • 没有找到相关文章

最新更新