0

所以,我一直在制作一个链表类,现在我正在尝试制作它,以便可以通过简单的 + 运算符来合并两个列表。这是当前的代码,整个:

#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;
}

然而,似乎 'aux' 在函数返回和 main() 中 'foo' 接收到的实际值之间丢失了,导致 foo.show() 无休止地显示随机数据。

我究竟做错了什么?

4

1 回答 1

0

没关系,找到问题了!

发生的事情是 operator= 正在对要传递的 List 进行“复制”,如果可以这么说的话。修改后的“重复”列表也会修改原始列表,所以在这里......

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 的每个元素都被一个一个地复制:

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

这样,接收 List 获得原始 List 的所有元素的副本,而不会成为它自己。

于 2012-10-14T16:26:37.673 回答