Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在链表中实现深度复制构造函数?_C++_Linked List_Copy Constructor_Deep Copy - Fatal编程技术网

C++ 如何在链表中实现深度复制构造函数?

C++ 如何在链表中实现深度复制构造函数?,c++,linked-list,copy-constructor,deep-copy,C++,Linked List,Copy Constructor,Deep Copy,对于我目前正在处理的这个问题,我尝试在这个链表中创建一个方法,该方法执行从一个项目到另一个项目的深度复制。现在,这个方法的内部是空的,因为我不能得到任何东西来为我的生活工作。有没有什么方法可以帮助我在下面注释的代码区域实现这个深度复制构造函数?谢谢 #include <string> #include <iostream> #include <cstddef> using std::string; class Item { public: str

对于我目前正在处理的这个问题,我尝试在这个链表中创建一个方法,该方法执行从一个项目到另一个项目的深度复制。现在,这个方法的内部是空的,因为我不能得到任何东西来为我的生活工作。有没有什么方法可以帮助我在下面注释的代码区域实现这个深度复制构造函数?谢谢

#include <string>
#include <iostream>
#include <cstddef>

using std::string;

class Item { 

public:

  string s; 

  Item(const char *a_s = "") { 
    s = a_s;
  }

  Item(string a_s) {
    s = a_s;
  }
};


class List {

  private:

      class ListNode { 

        public: 
          Item item; 
          ListNode * next; 
          ListNode(Item i) { 
            item = i;
            next = nullptr;
          }
      }; 

      ListNode * head; 
      ListNode * tail;

  public:

      class iterator {

        ListNode *node;

      public:
        iterator(ListNode *n = nullptr) {
          node = n;
        }

        Item& getItem() { return node->item; } //Not sure how this works
        void next() { node = node->next; }
        bool end() { return node==nullptr; }

      };



  public:

      List() {
        head = nullptr;
        tail = nullptr; //Sets the head and tail
      }

      List(const List & copy) { //Trying to create a copy constructor right here.

      }

      bool empty() { //Tells you if the list is empty
        return head==nullptr;
      }

      void append(Item a) { 

        ListNode *node = new ListNode(a);
          if ( head == nullptr ) {
            head = node;
            tail = node;
          } else {
            tail->next = node;
            tail = node;
          }
      }

      bool remove (Item &copy);

      void traverse() {
        ListNode *tmp = head;
        while(tmp != nullptr) {
          tmp = tmp->next;
        }
      }

      iterator begin() const {
        return iterator(head);
      }

};

    bool List::remove(Item &copy)
    {
      if (!empty()) {
        copy = head->item;
        ListNode *tmp = head->next;
        delete head;
        head = tmp;
        if (head==nullptr)
          tail = nullptr;
        return true;
      }
      return false;
    }


int main() {
   List l;
   l.append("eggs");

   List l2 = l; 

   std::cout << "done.\n";

   return 0;
}
#包括
#包括
#包括
使用std::string;
类项{
公众:
字符串s;
项目(const char*a_s=“”){
s=a_s;
}
项目(字符串a\u s){
s=a_s;
}
};
班级名单{
私人:
类ListNode{
公众:
项目;
ListNode*下一步;
ListNode(项目一){
项目=一;
next=nullptr;
}
}; 
ListNode*头;
ListNode*尾部;
公众:
类迭代器{
ListNode*节点;
公众:
迭代器(ListNode*n=nullptr){
节点=n;
}
Item&getItem(){return node->Item;}//不确定这是如何工作的
void next(){node=node->next;}
bool end(){return node==nullptr;}
};
公众:
列表(){
水头=零PTR;
tail=nullptr;//设置头部和尾部
}
List(const List©){//正在尝试在此处创建副本构造函数。
}
bool empty(){//告诉您列表是否为空
返回压头==nullptr;
}
无效附加(项目a){
ListNode*node=新的ListNode(a);
if(head==nullptr){
头部=节点;
尾=节点;
}否则{
tail->next=节点;
尾=节点;
}
}
bool删除(项目和副本);
无效遍历(){
ListNode*tmp=头部;
while(tmp!=nullptr){
tmp=tmp->next;
}
}
迭代器begin()常量{
返回迭代器(head);
}
};
bool列表::删除(项目和副本)
{
如果(!empty()){
复制=头->项目;
ListNode*tmp=head->next;
删除标题;
水头=tmp;
if(head==nullptr)
tail=nullptr;
返回true;
}
返回false;
}
int main(){
清单l;
l、 附加(“蛋”);
列表l2=l;
std::cout假设
append()
工作正常,您可以在循环中为
copy
中的每个项目重复调用它

考虑到您如何使用
tail
指针实现链表,这种方法使它成为一种理想的解决方案。您编写了
append
函数,因此只需以一种策略性的方式使用它

但是,请注意,如果在没有尾部指针的情况下实现了链表(必须遍历到链表的末尾以添加
append
),这种方法仍然有效,但效率很低,而且不令人满意

以下是一个示例(未经测试):

请注意,这没有针对边界条件进行测试,因此您可能需要检查
copy
是否为空,然后才能执行循环


初始化指向
nullptr
head
tail
指针,从传入列表的开头开始
copy
,然后调用
this->append()
copy
中的每个项目的循环中,直到到达
copy
的末尾。这是最简单的方法。您将代码写入了
append()
已经存在,所以只需重新使用它。@PaulMcKenzie的建议是通过使用
尾部
指针来实现的。通常情况下,我避免使用这种方法,因为每次插入之前,你都必须先寻找末端。
尾部
指针使搜索蓝精灵变得容易。不要忘记通过添加一个用于清理的析构函数和一个用于处理
列表l2;l2=l;
的赋值运算符,您可能会发现它们非常有用。@user4581301--是的,我一直在犹豫是否发布解决方案,直到我看到有一个尾部指针。一旦我看到列表的结尾是一个O(1)操作,那么就直接执行它并循环
append()
。因此,我想在for循环中使用append()函数将第一个对象中的项附加到第二个对象?@JohnHarrison--是的。您已经编写了所有代码,只是还没有弄清楚如何使用它。个人偏好:与其使用
尾部的额外
append
,不如使用
(copyNode!=nullptr)
。两者都将编译成相同的东西。比我想象的更简单。我因为没有明确说明要比较的内容而被编码标准搞砸了,所以我必须有
!=nullptr
,现在它已经根深蒂固了。谢天谢地,我不需要Yoda条件。
List(const List & copy) : head(nullptr), tail(nullptr) 
{ 
     ListNode *copyNode = copy.head;
     while (copyNode)
     {
         append(copyNode->item);
         copyNode = copyNode->next;
     }
 }