简体   繁体   English

链接列表和副本构造函数

[英]Linked list and copy constructor

I'm trying to write a basic, singly-linked list class in C++. 我正在尝试用C ++写一个基本的单链接列表类。 I did it in my data structures class years back, but I can't remember the details. 几年前,我在数据结构课程中做到了这一点,但我不记得详细信息了。

Should my Node class have a copy constructor? 我的Node类应该具有副本构造函数吗? It has a Node* as a member variable, and as far as I know you're always supposed to write a copy constructor, destructor, and assignment operator for classes that have dynamic members. 它以Node *作为成员变量,据我所知,您总是应该为具有动态成员的类编写一个复制构造函数,析构函数和赋值运算符。 But from what I've seen on the net, the List class takes care of the copying of Nodes. 但是根据我在网上看到的内容,List类负责节点的复制。 Is this really the case, and if so, why? 确实是这样吗?如果是这样,为什么?

For a basic singly-linked list class, I'd recommend: 对于基本的单链接列表类,我建议:

  • After you allocate each node, don't move nor copy the node after it's allocated 分配每个节点后,分配后不要移动或复制该节点
  • Therefore, disable the Node class copy contructor and assignment operator 因此,禁用Node类复制构造函数和赋值运算符

C++ generates a default copy contructor and assignment operator if you don't define them. 如果未定义,C ++会生成默认的复制构造函数和赋值运算符。 I recommend you disable these defaults, by declaring them as private and not implementing them. 我建议您禁用这些默认值,方法是将它们声明为私有而不执行它们。


But from what I've seen on the net, the List class takes care of the copying of Nodes. 但是根据我在网上看到的内容,List类负责节点的复制。 Is this really the case, and if so, why? 确实是这样吗?如果是这样,为什么?

It takes care of copying nodes because it supports copying (making a copy of) the entire list (which means making a copy of every node in the list). 它负责复制节点,因为它支持复制(复制)整个列表(这意味着复制列表中的每个节点)。

You don't need to support copying nodes, unless you support copying the whole list. 您无需支持复制节点,除非您支持复制整个列表。

You could do worse than copy the design of sgi's slist -- sgi's template library ("stl") was the basis for the part of the C++ standard library that's often still (not technically correctly;-) referred to as "stl". 您可能做的比复制sgi的slist的设计还要糟-sgi的模板库(“ stl”)是C ++标准库中经常仍然(在技术上不正确;-)称为“ stl”的部分的基础。 Unfortunately slist didn't make it (its doubly-linked cousin list OTOH did make it, and became std::list ) but I do like it. 不幸的是slist没做到(它的双链接表亲list OTOH做到了,并成为std::list ),但我确实喜欢它。

If you don't want to template the payload type and the allocator, it's fine to hard-code them, I guess; 我想,如果您不想为有效负载类型和分配器建立模板,则可以对它们进行硬编码。 but the key point to retain is that "nodes" are an internal implementation detail -- you only expose the container type, with all the nice, canonical aspects (and of course the payload type must be known -- it's not hard to template it, btw;-), and you make "node" an opaque class in your .h (which just contains a class node; , and pointers to it in your class slist ). 但是要保留的关键点是“节点”是内部实现的细节-您只需公开容器类型以及所有不错的规范方面即可(当然,必须知道有效负载类型-对其进行模板化并不难,btw ;-),然后将.h中的“节点”设置为不透明的类(它只包含一个class node;以及在class slist指向它的指针)。

If you had a singly linked list : 如果您有一个单链表:

A1 -> B1 -> C1

and your wrote your own copy constructor that, in turn calls the copy constructor on the internal Node* member, then you would get: 然后您编写了自己的副本构造函数,进而在内部Node *成员上调用了副本构造函数,那么您将获得:

A1 -> B1 -> C1
A2 -> B2 -> C2

What you should not do is call the implicitly generated copy constructor which will not perform a cascading copy, what you will get is: 您不应该执行的是调用隐式生成的副本构造函数,该构造函数将不执行级联副本,您将获得:

      A2
      |
      v
A1 -> B1 -> C1

So either write your own copy constructor to do a deep copy, or define an private copy constructor which implements a no-op. 因此,要么编写您自己的副本构造函数以进行深层复制,要么定义一个实现无操作的私有副本构造函数。

BTW the std::list implements a doubly linked list and implements deep copy semantics. 顺便说一句,std :: list实现了一个双向链接列表并实现了深层复制语义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM