0

したがって、Queue クラスの二重リンク リスト実装があります (以下を参照)。int と文字列をキューに入れようとすると、このキュー クラスは問題なく動作しますが、何らかの理由で、カスタム クラスをキューに入れようとすると、私のプログラムは決してenqueue()main で呼び出される行を過ぎて移動します。たぶん無限ループだと思いますが、よくわかりません。簡単に言えば、私のenqueue()メソッドが int、char、および string などの基本的なデータ型では機能するのに、カスタム クラスでは機能しないのはなぜですか?

これが私のキュークラスです...

//
//  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;
}
4

1 に答える 1

0

簡単に言うと、enqueue()メソッドがint、char、stringなどの基本的なデータ型で機能するのに、カスタムクラスでは機能しないのはなぜですか?

Stateクラスの詳細を提供しなかったため、確実に言うのは難しいですが、問題があるようです。生のポインターなどがあり、Queue :: enqueue()で使用する適切な代入演算子を実装していません。方法:

newNode->elem = T;

PSあなたはState実装を追加しました(ただし定義ではありません)が、それは内部でQueueクラス自体を使用していることを示しています。状態の代入は、コンパイラによって生成されたQueueの代入演算子を使用しますが、Queueクラスにはrawポインターがあるため、ヘッドポインターが二重に削除されます。

考えられる解決策の1つは、オブジェクト自体ではなく、キュー内にオブジェクトへのポインタを格納することです。

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オブジェクトのコピーと割り当てを禁止することをお勧めします。そうすれば、コンパイラはこのような問題を防ぐのに役立ちます。

于 2013-02-23T18:21:32.380 に答える