What is good practice? A copy constructor or a defensive copy method

2.3k views Asked by At

I have a class Graph and I need a copy of that graph. I am going to modify the internals of graph object ( eg: delete an edge etc. ). I have 2 ways to implement a graph.

  1. A copy constructor
  2. A method called 'getGraph() { return new Graph(this)}'. This method getGraph can do a defensive copy.

The only advantage of copy constructor, from my understanding is copy-at-will. This means if I dont want to modify graph object, there is not need for 'getGraph' to do a defensive copy.

Now coming back to my question.

  1. Is it better to use a copy constructor or is it better to use a function which returns copy of self object ?
  2. Why ?
4

There are 4 answers

2
Aniket Thakur On

As far I understand your question

In copy constructor you would do something like

Graph copy = new Graph(objectToBeCloned);

and in getGraph() you would do

Graph copy = objectToBeCloned.getGraph();

I suggest make your Graph class implement Cloneable interface and override clone() method to get a deep copy you need.

0
Joni On

Without knowing what you need this for, it's preferable to define copying as a method because a potential subclass can override a method. If Graph had a subclass that for example adds color to each node, calling a copy constructor in Graph you could only copy the plain graph, losing the additional information and functionality in subclasses. A method that copies the graph on the other hand could be overridden in the subclass.

You may find the Object.clone method helpful, but keeping in mind its requirements (have to implement Cloneble and override the clone method) and limitations (only makes a shallow copy) you might as well write your copy method from scratch.

0
Alexis On

I would say a copy constructor have more semantics over a getGraph method inside a Graph object. So between the two I would prefer a copy constructor.

Please don't consider using clone, it is broken by design, read Object Identity for more information about it. You have also some alternatives, that are expressed here : clone vs copy constructor

0
Naresh Joshi On

I am not sure if you are still looking for the answer to this question but because the question is not marked as answered, I am going to answer it.

Since you had chosen to go with the copy constructor

Graph clonedGraph = new Graph(originalGraph);

or defensive copy

Graph clonedGraph = originalGraph.getGraph();

I can tell that you are aware of the disadvantages of Object.clone(), And I will suggest you go with defensive copy strategy because it is polymorphic and also give you the advantage of inversion control or dependency injection.

Copy constructor strategy will fail if you have a child class of Graph (Which you might need in future) and try to assign the object of that child class to the reference of Graph and then try to create copy for it. You can read more on Java Cloning - Why Copy Constructors Are Not Sufficient