2013-08-09 5 views
5
  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 ..いくつかのクラスは深いコピーを実装するのを忘れた場合はどう?安全な深くコピーされたオブジェクトを決して持っていないことを意味しますか?これを防ぐ方法はありますか?

+0

これを行うことを敢えてしないでください! http://stackoverflow.com/q/2156120/1065197 –

+1

を参照してください。「不変性を好む」と表示されている場合は、このようなことを心配する必要はありません。 –

答えて

5

あなたは守備的なはずですか?
必要がある場合のみ。

あなたはどれくらい深く行くべきですか?
あなたが必要とするほど深い。

Sound trite?さて、これらのタイプの質問に対する基本的な答えは、「必要な機能を提供するために必要なだけの作業」です。

2

一般的に呼び出しコードを信頼しない限り、守備コピーを作成しないでください。

Do:インターフェイスを文書化し、問題を引き起こす可能性のあるものがあればそれらを変更することはできません。

時々: 2つのコンストラクタを提供します。 1つはオブジェクトを使用します。 1人はコピーを作る。次に、発信者が必要に応じてコピーを作成するようにします。呼び出し元は、コンストラクタを呼び出した直後にそのオブジェクトへの参照を破棄することがあります。その場合、コピーは必要ありません。

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

あなたは、呼び出し元のコードを信頼する場合:問題を無視します。あなたのコードを呼び出す前に(それ自身の視点から)破棄しないもののコピーを作ることを期待してください。

パラノイアは、彼らがあなたを手に入れないことを意味しません。しかし、彼らがどちらかであることを意味するわけではありません。

関連する問題