【问题标题】:C++: Copy constructor is deleting nodes in original objectC ++:复制构造函数正在删除原始对象中的节点
【发布时间】:2015-01-30 05:41:21
【问题描述】:

我已经使用模板类实现了一个单链表,并尝试创建一个工作副本构造函数。当调用复制构造函数时,它会准确地复制列表。但是,它会从原始节点中删除节点。

这是类的实现、构造函数和析构函数:

template<class L>
class LinkedList
{
public:
        LinkedList();
        LinkedList(const LinkedList<L> &og);
        ~LinkedList();

        Node<L>* AddToEnd(L object);
        Node<L>* AddToMiddle(L object);
        Node<L>* DeleteNode(L deleteItem);
        Node<L>* ReverseList();
        void Display();
        int Size();

private:
        Node<L>* head;
        Node<L>* tail;
        int size;
};

template<class L>
LinkedList<L>::LinkedList()
{
        head = NULL;
        tail = NULL;
        size = 0;
}

template<class L>
LinkedList<L>::LinkedList(const LinkedList<L> &og)
{
    cout << "\nCopy constructor has been called.\n\n";
    head = new Node<L>;
    *head = *og.head;

    tail = new Node<L>;
    *tail = *og.tail;

    size = og.size;
}

template<class L>
LinkedList<L>::~LinkedList()
{
    delete head;
    delete tail;
}

还有main.cpp:

#include "Header.h"

int main()
{
        int int1 = 1;
        int int2 = 2;
        int int3 = 3;
        int int4 = 4;
        int int5 = 5;

        cout << "Creating the first integer list..." << endl;

        LinkedList<int> intList1;

        intList1.AddToEnd(int1);
        intList1.AddToEnd(int2);
        intList1.AddToEnd(int3);
        intList1.AddToEnd(int4);
        intList1.AddToEnd(int5);

        intList1.Display();

        cout << endl << "Cloning and reversing..." << endl;

        LinkedList<int> intList2(intList1);
        intList2.ReverseList();

        cout << "Original list: " << endl;

        intList1.Display();

        cout << "Reversed list: " << endl;

        intList2.Display();

        return 0;
}

输出如下:

正在创建第一个整数列表... 1 2 3 4 5

克隆和反转...

复制构造函数已被调用。

原名单: 1 2 1 反转列表: 5 4 3 2 1

【问题讨论】:

    标签: c++ class templates constructor linked-list


    【解决方案1】:

    您的复制构造函数完全错误。您应该遍历链接列表并复制该列表的每个元素。你的尾巴也应该指向列表的最后一个元素。 所以代码应该是这样的。

    template<class L>
    LinkedList<L>::LinkedList(const LinkedList<L> &og)
    {
        cout << "\nCopy constructor has been called.\n\n";
        head = new Node<L>;
        *head = *og.head;
    
        Node *p  = og.head->next;
        Node *i = head;
        while (p != NULL) {
            i->next = new Node<L>;
            *(i->next) = *p;
            p = p->next;
            i = i->next;
        }
    
        tail = i;
        size = og.size;
    }
    

    【讨论】:

      【解决方案2】:

      您的复制构造函数定义需要比现在做的更多。

      现在你所做的只是复制头和尾指针,这还不够。这样,您的克隆列表与第一个列表基本相同。您需要做的是复制每个节点,例如:

      for (Node<L>* n = og.first(); n != NULL ; n = n->next()) {
          this->AddToEnd(n->value());
      } 
      

      此外,您的析构函数没有正确清理。您可能想要删除您可能已添加的所有节点。

      【讨论】:

      • 用这种方法试过了——不起作用。 template&lt;class L&gt; LinkedList&lt;L&gt;::LinkedList(const LinkedList&lt;L&gt; &amp;og) { head = new Node&lt;L&gt;; tail = new Node&lt;L&gt;; *tail = *og.tail; *head = *og.head; for(Node&lt;L&gt;* ptr = og.head; ptr != NULL; ptr = ptr-&gt;next) { this-&gt;AddToEnd(ptr-&gt;data); } size = og.size; }
      【解决方案3】:

      让您的复制构造函数遍历og 列表中的节点并将它们附加到您的列表中:

      template<class L>
      LinkedList<L>::LinkedList(const LinkedList<L> &og)
          : head(NULL)
          , tail(NULL)
      {
      
          for (Node* p(og.head); p != NULL; p = p->next)
          {
              AddToEnd(p->value);
          }
      }
      

      其中valueNode 包含的数据。

      你的析构函数也不正确。它应该遍历列表并一一删除节点。如果元素较多,只删除headtail会导致整个列表丢失:

      template<class L>
      LinkedList<L>::~LinkedList()
      {
          while (head)
          {
              Node<L>* temp(head);
              head = head->next;
              delete temp;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-04-12
        • 2012-11-24
        • 2012-08-14
        • 2013-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多