Бесконечный цикл (?) При попытке поместить экземпляр пользовательского класса в очередь

Итак, у меня есть реализация класса 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() это не проблема, так как «DONE» печатает, когда я вставляю его перед .enqueue() вызов…
Какие-нибудь мысли?

заранее спасибо

РЕДАКТИРОВАТЬ: вот конструктор по умолчанию, конструктор копирования, деструктор и перегруженный оператор присваивания для моего 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

Решение

Короткий рассказ, почему мой метод 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, чтобы компилятор помог вам предотвратить подобные проблемы.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector