【问题标题】:Uniting a dynamic list in C++ with overloaded operators将 C++ 中的动态列表与重载运算符联合起来
【发布时间】:2012-10-14 04:29:37
【问题描述】:

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

#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() 无休止地显示随机数据。

我做错了什么?

【问题讨论】:

    标签: list linked-list operator-overloading dynamic-data


    【解决方案1】:

    没关系,找到问题了!

    发生的事情是 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 的所有元素的副本,而不会成为它自己。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      相关资源
      最近更新 更多