【问题标题】:How deep should copy constructors get复制构造函数应该有多深
【发布时间】:2013-08-09 22:00:02
【问题描述】:
  1. 是否应始终为传递给构造函数的可变对象的对象引用制作防御性副本?

  2. 如果是,那么我在制作副本时应该“深入”到什么程度。在下面的示例中,我应该在所有涉及的类的复制构造函数中进行深度复制吗?

例如:

class Graph {
    AdjacencyList;
    public Graph(Graph graph) {
      this.list = graph.list;   // shallow copy
      OR
      this.list = ArrayCopy(graph.list);  // deep copy
    }
}

class DFS implements GraphAlgo {
   Graph g
   DFS(Graph g) {
     this.g = g;   // shallow copy
     OR
     this.g = new Graph(graph)  // deep copy
   }

   DFS(Algo algo) {
     this.g = algo.g;  // shallow copy
     OR
     this.g = new Graph(algo.g);  // deep copy
   }

}

class Algo {
   GraphAlgo galgo

   Algo (GraphAlgo dfsalgo) {
      galgo  = dfsalgo  // shallow copy
      OR
      galgo = new DFSAlgo(dfsalgo); // deep copy
   }
}

3.. 如果某个类忘记实现深拷贝怎么办?这是否意味着我永远不会有一个安全的深度复制对象?有什么办法可以防止这种情况发生?

【问题讨论】:

标签: java constructor deep-copy


【解决方案1】:

你应该防守吗?
仅当您需要时。

你应该去多深?
尽可能深。

听起来很老套?嗯,这类问题的基本答案是“尽你所能提供所需的功能”。

【讨论】:

    【解决方案2】:

    通常:除非您不信任调用代码,否则不要制作防御性副本。

    做:记录界面,并说如果这会导致问题,则不允许他们更改他们传递给您的任何内容。

    有时:提供两个构造函数。一个使用对象。一个人制作副本。然后让调用者在需要时调用制作副本的人。调用者很可能在调用您的构造函数之后丢弃对该对象的任何引用。在这种情况下,不需要副本。

    Algo (GraphAlgo dfsalgo, boolean doCopy) {
        if (doCopy) {
            galgo = new DFSAlgo(dfsalgo); // deep copy
        } else {
            galgo  = dfsalgo  // shallow copy
        }
    }
    

    如果您信任调用代码:请忽略该问题。期望它在调用您的代码之前复制任何它不会丢弃的东西(从它自己的角度来看)。

    偏执狂并不意味着他们不会来抓你。但这并不意味着它们也是。

    【讨论】:

      猜你喜欢
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 2010-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多