问题描述
作为我任务的一部分,我们被要求创建一个构造函数,该构造函数将对另一个列表进行深度复制。 以下是我们对它的描述。
复制构造函数:实现一个接受 DSList 对象的复制构造函数。复制构造函数应该执行传递给构造函数的 DSList 的深层复制:新的 DSList 不应包含对第二个 DSList 中的 Node 对象的引用。 (两个 DSList 应该是独立的:更改一个 DSList 中 Node 对象的内容不应影响另一个)。
你们能帮我复制构造函数吗?我不知道怎么写。
非常感谢您提供的任何见解。谢谢。
下面是 DSList
类的第一部分。
public class DSList implements List {
public Node head;
/**
* This is a constructor of the DSList class.
* The constructor takes no parameters.
*/
public DSList() {
}
/**
* This is a constructor of the DSList class.
* The constructor takes in one parameter and
* set this to the given node.
* @param head_ is the given node.
*/
public DSList(Node head_) {
this.head = head_;
}
/**
* This is the copy constructor. The constructor takes in another DSList object and copy it to
* a new DSList. Each copy created is independent of the original DSList.
* @param other is another DSList object.
*/
public DSList(DSList other) { // copy constructor.
// this needs to be filled///
}
除此之外,我们还提供了单独的 Node 类和 Token 类(如下所示)。
public class Node {
public Node next;
public Node prev;
private Token t;
public Node(Node next,Node prev,Token token) {
this.next = next;
this.prev = prev;
this.t = token;
}
public Token getToken() {
return t;
}
@Override
public boolean equals(Object other) {
if (this == other)
return true;
if (other == null)
return false;
if (!(other instanceof Node))
return false;
return t.equals(((Node)other).getToken());
}
@Override
public int hashCode() {
if ( t == null )
return 0;
return t.hashCode();
}
}
public class Token {
public enum Type { OPERATOR,OPERAND,PAREN };
public Type type;
private String operator;
private double operand;
public Token(double result) {
this.operand = result;
this.type = Type.OPERAND;
}
public Token(String op) {
this.operator = op;
this.type = Type.OPERATOR;
if ( this.operator.equals("(") || this.operator.equals(")") ) {
this.type = Type.PAREN;
}
}
public Token(Token other) {
this.operator = other.operator;
this.operand = other.operand;
this.type = other.type;
}
public String getoperator() {
return operator;
}
public double getoperand() {
return operand;
}
public int getPrecedence() {
if ( type == Type.PAREN )
return -1;
if ( type != Type.OPERATOR )
return 0;
switch ( operator ) {
case "+":
case "-":
return 0;
case "*":
case "/":
return 2;
}
return 0;
}
@Override
public boolean equals(Object obj) {
if ( obj == null )
return false;
if ( obj == this )
return false;
if ( !obj.getClass().equals(Token.class))
return false;
Token t = (Token)obj;
if ( t.type == this.type ) {
if ( this.type == Type.OPERATOR )
return operator.equals(t.operator);
else
return operand == t.operand;
}
return false;
}
@Override
public int hashCode() {
return 0;
}
public String toString() {
return this.type == Type.OPERAND ? "" + this.operand : this.operator;
}
}
解决方法
带有签名 public Token(Token other) 的构造函数是复制构造函数的一个很好的例子。调用构造函数,然后将其他 Token 的成员设置为与新 Token 的成员相同。
您有一个由许多链接在一起的节点组成的 DSList。如果要复制所有这些节点,则必须创建一个新的空 DSList。此 DSList 将包含原始 DSList 中节点的所有副本。接下来,您需要遍历原始 DSList 中的所有节点,通过在每个节点上调用复制构造函数来复制节点,然后将这些节点插入到新的 DSList 中。这意味着您将在 Token 和 Node 上调用复制构造函数,因为 DSList 包含对 Node 的引用,而 Node 包含对 Token 的引用。完成此过程后,新的 DSList 将是原始 DSList 的深拷贝版本。
代码最终看起来像这样。
public DSList(DSList original)
{
DSList newListCopy = new DSList();
if (this.head != null)
{
// Call the copy constructor for the head node and save the head for the new list.
newListCopy.head = new Node(this.head);
// Temporary variables for inserting and iterating lists.
Node newLinkedNode = newListCopy.head;
Node iterator = this.head.next;
// Looping through the lists.
while (iterator != null)
{
// Insert the copy of the node from the other list.
Node prev = newLinkedNode;
newLinkedNode.next = new Node(iterator);
newLinkedNode = newLinkedNode.next;
newLinkedNode.prev = prev;
iterator = iterator.next;
}
}
return newListCopy;
}
一个关键的见解是,如果您有对象,则必须通过使用 new 创建该对象的新实例来复制它们。对于属于您要复制的对象的一部分的所有对象,您都需要像 token 中的复制构造函数。