这是作业
我正在为我的C ++类实现一个链表类,而且复制构造函数对我来说非常混乱。
链表由名为Elems:
的结构组成struct Elem
{
int pri;
data info;
Elem * next;
};
Elem * head;
info是一个单独的自定义类,存储在Elem中。
复制构造函数的签名是:
linkedList::linkedList( const linkedList &v )
我遇到的问题主要是采用我的逻辑并将其编写为代码。
我的总体想法是:
这是一般的想法吗?
任何帮助都会很棒。 请记住,这是作业,所以请不要直接回答!
感谢您的时间
=============================================== ================================================== ================================================== =================
感谢大家的时间!
我想我已经弄明白了:
//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;
}
我很确定这很有效。我画了一些逻辑图片来帮助,我没有遇到任何问题。
答案 0 :(得分:21)
您必须小心步骤1和步骤2的一部分。步骤1应分配一个新节点并将其用作head
。在第2步中,除非您打算制作浅层副本,否则关于next = v.next
的部分不正确。
复制诸如链表之类的容器时,您可能需要深层复制,因此需要创建新节点并仅复制数据。新列表的节点中的next
和prior
指针应引用您为该列表创建特定的新节点,而不是原始列表中的节点。这些新节点将具有原始列表中相应数据的副本,因此可以将新列表视为值或深度副本。
这是描绘浅层和深层复制之间差异的图片:
请注意,在图的 Deep Copy 部分中,没有一个节点指向旧列表中的节点。有关浅拷贝和深拷贝之间差异的更多信息,请参阅object copying上的维基百科文章。
答案 1 :(得分:4)
您不应设置this->head = v.head
。因为头部只是一个指针。您需要做的是创建一个新头并将值从v.head
单独复制到新头中。否则你会有两个指向同一事物的指针。
然后,您必须创建一个以Elem
开头的临时v.head
指针,并遍历列表,将其值复制到新Elem
指针到新副本中。
见上文。
答案 2 :(得分:2)
你的复制构造函数应该复制什么?它应该复制pri
- 简单。它应该复制info
- 也很容易。如果next
不为null,它也应该复制它。如何复制next
?认为是递归的:好吧,next
是Elem *
,而Elem
有一个复制构造函数:只需使用它来复制引用的Elem
并引用它。
你也可以迭代地解决这个问题,但递归解决方案更加直观。
答案 3 :(得分:0)
所以这是我的答案(不知道这是否适合你的作业 - 教师有时会有自己的想法;):
通常,复制构造函数应该“复制”您的对象。即假设你有linkedList l1,并做一个linkedList l2 = l1(调用linkedList :: linkedList(l1)),然后是l1和l2 在l1的修改不影响l2的意义上是完全独立的对象,反之亦然。
当您只是分配指针时,您将无法获得真正的副本,因为取消引用和修改它们中的任何一个都会影响这两个对象。
您更愿意为源列表中的每个元素制作一个真正的深层副本(或者,如果您想要的话,只进行按需复制)。
答案 4 :(得分:0)
你忘了这条线
return;
后
if( v.head == 0 )
head = 0;
你需要离开,对吧?