为链表创建复制构造函数
这是家庭作业
我正在为我的 C++ 类实现一个链表类,而复制构造函数对我来说非常令人困惑。
链表由称为 Elems 的结构组成:
struct Elem
{
int pri;
data info;
Elem * next;
};
Elem * head;
info 是存储在 Elem 中的单独的自定义类。
复制构造函数的签名是:
linkedList::linkedList( const linkedList &v )
我遇到的问题主要是采用我的逻辑并将其实际编写为代码。
我的总体想法是:
- 将 head 设置为 v.head (head = v.head)
- 将 Elem 的值设置为 v's (pri = v.pri , info = v.info , next = v.next)
- 迭代,重复步骤 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;
}
我很确定这是可行的。我画了一些逻辑图来提供帮助,但没有遇到任何问题。
This is homework
I'm working on implementing a linked list class for my C++ class, and the copy constructor has be very confusing for me.
The linked list is comprised of structs called Elems:
struct Elem
{
int pri;
data info;
Elem * next;
};
Elem * head;
info is a separate, custom class that is stored in the Elem.
the signature for the copy constructor is:
linkedList::linkedList( const linkedList &v )
The issue I am having is mostly taking my logic and actually writing it as code.
My general idea is to:
- Set head to v.head (head = v.head)
- Set the Elem's values to v's (pri = v.pri , info = v.info , next = v.next)
- Iterate through, repeating step 2.
Is this the general idea?
Any help would be great. Remember, this is homework, so no direct answers please!
Thank you for your time
====================================================================================================================================================================
Thanks for your time everybody!
I think I have it figured out:
//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;
}
I'm pretty sure that works. I drew some logical pictures to help, and I didn't run into any issues.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您必须小心步骤 1 和步骤 2 的一部分。步骤 1 应分配一个新节点并将其用作
head
。在步骤 2 中,有关next = v.next
的部分,除非您的目的是进行浅复制,否则是不正确的。当您复制链表等容器时,您可能需要深层复制,因此需要创建新节点并且仅复制数据。新列表节点中的
next
和prior
指针应引用您专门为该列表创建的新节点,而不是来自原始清单。这些新节点将具有原始列表中相应数据的副本,因此新列表可以被视为按值或深度副本。下面是一张图片,描述了浅复制和深复制之间的差异:
注意深复制中的情况 图中的部分,没有一个节点指向旧列表中的节点。有关浅拷贝和深拷贝之间差异的更多信息,请参阅有关对象复制的 Wikipedia 文章。
You have to be careful with Step 1 and part of Step 2. Step 1 should allocate a new node and use that as the
head
. In Step 2, the part aboutnext = v.next
, unless your intention is to make a shallow copy, is incorrect.When you copy a container such as a linked list, you probably want a deep copy, so new nodes need to be created and only the data copied over. The
next
andprior
pointers in the nodes of the new list should refer to new nodes you create specifically for that list and not the nodes from the original list. These new nodes would have copies of the corresponding data from the original list, so that the new list can be considered a by value, or deep copy.Here is a picture depicting the differences between shallow and deep copying:
Notice how in the Deep Copy portion of the diagram, none of the nodes point to nodes in the old list. For more information about the difference between shallow and deep copies, see the Wikipedia article on object copying.
您不应该设置
this->head = v.head
。因为头只是一个指针。您需要做的是创建一个新头并将值从v.head
单独复制到新头中。否则,您将有两个指针指向同一事物。然后,您必须创建一个以
v.head
开头的临时Elem
指针,并迭代列表,将其值复制到新的Elem
code> 指向新副本的指针。见上文。
You shouldn't set
this->head = v.head
. Because the head is simply a pointer. What you need to do is to create a new head and copy the values individually fromv.head
into your new head. Otherwise you'd have two pointers pointing to the same thing.You then would have to create a temporary
Elem
pointer that starts withv.head
and iterate through the list, copying its values to newElem
pointers into the new copy.See above.
您的复制构造函数应该复制什么?它应该复制
pri
- 简单。它应该复制info
- 也很简单。如果next
不为空,它也应该复制它。如何复制下一个
?思考递归:嗯,next
是一个Elem *
,并且Elem
有一个复制构造函数:只需使用它来复制引用的Elem
并参考它。您也可以迭代地解决这个问题,但递归解决方案更加直观。
What should your copy constructor copy? It should copy
pri
- easy. It should copyinfo
- easy as well. And ifnext
is not null, it should copy it, too. How can you copynext
? Think recursive: Well,next
is anElem *
, andElem
has a copy constructor: Just use it to copy the referencedElem
and refer to it.You can solve this iteratively, too, but the recursive solution is much more intuitive.
所以这是我的答案(不知道这是否适合您的作业 - 教师有时往往有自己的想法;):
通常,复制构造函数应该“复制”您的对象。也就是说,你有 linkedList l1,并执行 linkedList l2 = l1 (调用 linkedList::linkedList(l1)),然后是 l1 和 l2
是完全独立的对象,因为 l1 的修改不会影响 l2,反之亦然。
当您只分配指针时,您将不会获得真正的副本,因为取消引用和修改其中任何一个都会影响两个对象。
您宁愿对源列表中的每个元素进行真正的深层复制(或者如果您想要更花哨,则仅进行按需复制)。
So here is my answer (don't know if that fits to your homework or not - instructors tend to have their own ideas sometimes ;):
Generally a copy constructor should "copy" your object. I.e. say you have linkedList l1, and do a linkedList l2 = l1 (which calls linkedList::linkedList(l1)), then l1 and l2
are totally separate objects in the sense that modification of l1 doesn't affect l2 and vice versa.
When you just assign pointers you won't get a real copy, as dereferencing and modifying either of them would affect both objects.
You rather want to make a real deep copy of every element in your source list (or do a copy-on-demand only, if you want to be fancy).
你忘记了线
返回;
之后
你需要出去,对吧?
You forgot the line
return;
after
You need to get out, right?