所以我有一个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对象,这样编译器可以帮助您防止类似的问题。