【问题标题】:Creating a copy constructor for a linked list为链表创建复制构造函数
【发布时间】:2011-12-10 08:17:42
【问题描述】:

这是作业

我正在为我的 C++ 类实现一个链表类,而复制构造函数让我很困惑。

链表由称为 Elems 的结构组成:

struct Elem 
    {
        int pri;
        data info;
        Elem * next;
    };
    Elem * head;

info 是一个单独的自定义类,存储在 Elem 中。

复制构造函数的签名是:

linkedList::linkedList( const linkedList &v )

我遇到的问题主要是把我的逻辑写成代码。

我的总体思路是:

  1. 将 head 设置为 v.head (head = v.head)
  2. 将 Elem 的值设置为 v (pri = v.pri , info = v.info , next = v.next)
  3. 遍历,重复第 2 步。

这是大意吗?

任何帮助都会很棒。 记住,这是作业,所以请不要直接回答!

感谢您的宝贵时间

================================================ ==================================================== ==================================================== =================

感谢大家的宝贵时间!

我想我已经明白了:

//Copy Constructor
LinkedList::LinkedList( const LinkedList &v )
{
Elem * p1 = 0;//current
Elem * p2 = 0;//next

if( v.head == 0 )
    head = 0;

else
{
    head = new Elem;
    head -> pri = v.head -> pri;
    head -> info = v.head -> info;

    p1 = head;
    p2 = v.head -> next;
}

while( p2 )
{
    p1 -> next = new Elem;
    p1 = p1 -> next;
    p1 -> pri = p2 -> pri;
    p1 -> info = p2 -> info;

    p2 = p2 -> next;
}
p1 -> next = 0;
}

我很确定这行得通。我画了一些合乎逻辑的图片来帮忙,我没有遇到任何问题。

【问题讨论】:

  • 复制构造函数到底应该做什么?使用适当的链接生成每个节点的副本听起来很合理,但这不是唯一的可能性。
  • +1 用于直截了当地写作业并要求不直接回答
  • 感谢您给我正确的提示!我为我的节点实现了一个深拷贝构造函数,以便能够返回一个带有父节点及其父节点的引用结构的“最终”节点的对象......以保持完整。将其用于树搜索算法

标签: c++ linked-list copy-constructor


【解决方案1】:

您必须小心第 1 步和第 2 步的一部分。第 1 步应分配一个新节点并将其用作head。在第 2 步中,关于 next = v.next 的部分,除非您的意图是进行浅拷贝,否则是不正确的。

当您复制链表等容器时,您可能需要深度复制,因此需要创建新节点并且只复制数据。新列表节点中的nextprior 指针应该指代您为该列表创建的新节点专门,而不是原始列表中的节点。这些新节点将拥有原始列表中相应数据的副本,因此可以将新列表视为按值复制或深层复制。

下面这张图描述了浅拷贝和深拷贝的区别:

请注意,在图表的 深拷贝 部分中,没有一个节点指向旧列表中的节点。有关浅拷贝和深拷贝之间区别的更多信息,请参阅object copying 上的维基百科文章。

【讨论】:

  • 哦!图片!这肯定有助于澄清。 +1
【解决方案2】:
  1. 你不应该设置this->head = v.head。因为头部只是一个指针。您需要做的是创建一个新头并将 v.head 中的值单独复制到您的新头中。否则你会有两个指针指向同一个东西。

  2. 然后您必须创建一个以v.head 开头的临时Elem 指针并遍历列表,将其值复制到新的Elem 指针到新副本中。

    李>
  3. 见上文。

【讨论】:

  • 注意:当你复制它的值时,不要不要复制它的指针。通常,永远不要在复制构造函数中复制指针。复制指向的对象。
【解决方案3】:

你的拷贝构造函数应该拷贝什么?它应该复制pri - 很简单。它也应该复制info- easy。如果next 不为空,它也应该复制它。你怎么能复制next?考虑递归:好吧,next 是一个Elem *,而Elem 有一个复制构造函数:只需使用它来复制引用的Elem 并引用它。

您也可以迭代解决这个问题,但递归解决方案更直观。

【讨论】:

  • 没错,如果 Elem 有一个复制构造函数,这很容易
  • 我们故意不做递归,所以我们可以更容易地看到发生了什么。他向我们展示了递归方式,并故意说如果我们这样做,我们会失败。 O_O
  • @Joshua:你应该提到这样的限制。
【解决方案4】:

所以这是我的答案(不知道这是否适合您的作业 - 教师有时往往有自己的想法;):

通常,复制构造函数应该“复制”您的对象。 IE。假设你有linkedList l1,然后做一个linkedList l2 = l1(调用linkedList::linkedList(l1)),然后是l1和l2 是完全独立的对象,因为修改 l1 不会影响 l2,反之亦然。

当您只分配指针时,您不会获得真正的副本,因为取消引用和修改其中任何一个都会影响两个对象。

您宁愿对源列表中的每个元素都进行真正的深度复制(或者只按需复制,如果您想花哨的话)。

【讨论】:

    【解决方案5】:

    你忘记了线路 return; 之后

    if( v.head == 0 )
        head = 0;
    

    你需要出去,对吧?

    【讨论】:

      猜你喜欢
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多