0

それで、私はリンクされたリスト クラスを作成する過程にあり、現在、単純な a + 演算子を使用して 2 つのリストを結合できるように作成しようとしています。現在のコード全体は次のとおりです。

#include <iostream>
using namespace std;

// ---/ List Class /--- //

template <class Type>
struct Node {
    Type core;
    Node<Type> *next;
};

template <class Type>
class List {
    public:
        Node<Type> *start, *end;
        unsigned int siz;

        static const int END;

    public:
        // Genesis
        List() {
            start = NULL;
            end = NULL;

            siz = 0;
        };

        // ---
        void push (const Type&, const int&);

        // DEBUG
        void show (void);

        // +-*/
        List operator+ (const List&);
        List& operator= (const List&);
        List& operator+= (const List&);

        // Abbadon
        ~List() {
            delete start;
            delete end;
        };
};

template <class Type>
const int List<Type>::END = -1;

// ---

template <class Type>
void List<Type>::push (const Type& elem, const int& pos = END) {
    Node<Type> *aux;

    aux = new Node<Type>;
    aux->core = elem;

    if (siz == 0) {
        aux->next = NULL;

        start = aux;
        end = aux;
    }
    else {
        if (pos == END) {
            aux->next = NULL;

            end->next = aux;
            end = end->next;
        }
        else if (pos == 0) {
            aux->next = start;

            start = aux;
        }
        else {
            Node<Type> *pesq = start;
            for (int i = 1; (i < pos) && (pesq->next != NULL); i++) {
                pesq = pesq->next;
            }

            aux->next = pesq->next;
            pesq->next = aux;
        }
    }

    siz++;
}

// DEBUG

template <class Type>
void List<Type>::show (void) {
    Node<Type> *pesq = start;
    while (pesq != NULL) {
        cout << pesq->core << endl;
        pesq = pesq->next;
    }

    cin.get();
}

// +-*/

template <class Type>
List<Type> List<Type>::operator+ (const List<Type>& nimda) {
    List<Type> aux = *this;

    aux.end->next = nimda.start;
    aux.end = nimda.end;

    aux.siz += nimda.siz;

    return aux;
}

template <class Type>
List<Type>& List<Type>::operator= (const List<Type>& nimda) {
    if (&nimda != this) {
        start = nimda.start;
        end = nimda.start;
        siz = nimda.siz;
    }
} 

template <class Type>
List<Type>& List<Type>::operator+= (const List<Type>& nimda) {
    *this = *this + nimda;  
    return *this;
}

// ---/ MAIN() /--- //

int main() {
    List<int> adabo;
    List<int> inakos;

    adabo.push(1);
    adabo.push(2);

    inakos.push(3);
    inakos.push(4);

    adabo = adabo + inakos;

    adabo.show();
}

オーバーロードされた演算子は次のとおりです。

template <class Type>
List<Type> List<Type>::operator+ (const List<Type>& nimda) {
    List<Type> aux = *this;

    aux.end->next = nimda.start;
    aux.end = nimda.end;

    aux.siz += nimda.siz;

    return aux;
}

template <class Type>
List<Type>& List<Type>::operator= (const List<Type>& nimda) {
    if (&nimda != this) {
        start = nimda.start;
        end = nimda.start;
        siz = nimda.siz;
    }
} 

template <class Type>
List<Type>& List<Type>::operator+= (const List<Type>& nimda) {
    *this = *this + nimda;  
    return *this;
}

テスト用の main() は次のとおりです。

// ---/ MAIN() /--- //

int main() {
    List<int> adabo;
    List<int> inakos;
    List<int> foo;

    adabo.push(1);
    adabo.push(2);

    inakos.push(3);
    inakos.push(4);

    foo = adabo + inakos;

    foo.show();
}

その出力はおそらく値 1、2、3、および 4 であり、aux が戻る前に + の演算子に show 関数を入れると実際に発生します。

template <class Type>
List<Type> List<Type>::operator+ (const List<Type>& nimda) {
    List<Type> aux = *this;

    aux.end->next = nimda.start;
    aux.end = nimda.end;

    aux.siz += nimda.siz;

    aux.show() // Putting it here shows everything as expected

    return aux;
}

ただし、関数の戻り値と main() で 'foo' が受け取る実際の値の間のどこかで 'aux' が失われ、foo.show() がランダムなデータを際限なく表示するようです。

私は何を間違っていますか?

4

1 に答える 1

0

問題が見つかりました。

何が起こっていたかというと、operator= は、渡されるリストの「複製」を作成していました。「複製」リストを変更すると、元のリストも変更されるため、ここでは...

template <class Type>
List<Type> List<Type>::operator+ (const List<Type>& nimda) {
    List<Type> aux = *this; // ...aux, which would become a duplicate of the class...

    aux.end->next = nimda.start;
    aux.end = nimda.end;

    aux.siz += nimda.siz;

    return aux;
} // ...when destructed here, would destruct *this just as well, making all data be lost.

この問題を解決するには、オーバーロードされた =...

template <class Type>
List<Type>& List<Type>::operator= (const List<Type>& nimda) {
    if (&nimda != this) {
        start = nimda.start;
        end = nimda.start;
        siz = nimda.siz;
    }
} 

...これで、List の各要素が 1 つずつコピーされるようになりました。

template <class Type>
List<Type>& List<Type>::operator= (const List<Type>& nimda) {
    if (&nimda != this) {
        kill();

        Node<Type> *aux = nimda.start;
        while (aux != NULL) {
            push(aux->core);
            aux = aux->next;
        }
    }
}

このようにして、受信リストは、それ自体になることなく、元のリストのすべての要素のコピーを取得します。

于 2012-10-14T16:26:37.673 に答える