1

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 ?
JavaDeveloper
  • 5,320
  • 16
  • 79
  • 132
  • Why do you have `getGraph` method in `Graph` class? Are you having a reference to a `Graph` instance in the `Graph` class itself? – Rohit Jain Aug 22 '13 at 06:27
  • yes. its kind of return this. – JavaDeveloper Aug 22 '13 at 06:28
  • What is a copy constructor and what is a defensive copy? I think you need deep copy. – Aniket Thakur Aug 22 '13 at 06:28
  • @JavaDeveloper. Now that sounds strange. Can you show your current code? And elaborate more onto why you actually need this? – Rohit Jain Aug 22 '13 at 06:29
  • I understand i need a deep copy, but is it via a copy-constructor or via an explicit method that does a deep copy ?? – JavaDeveloper Aug 22 '13 at 06:30
  • @JavaDeveloper. The best way to make a deep copy is via serialization. A copy constructor is good. But if your objects contains reference to some mutable object, which in turn again contains a mutable object, you would need to make deep copy of all of them. Serialization will take care of that. – Rohit Jain Aug 22 '13 at 06:32

4 Answers4

2

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.

Joni
  • 108,737
  • 14
  • 143
  • 193
1

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.

Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
  • Thanks for help, but my question is which of the following options is a better one ? – JavaDeveloper Aug 22 '13 at 06:38
  • Performance wise I think none. It's merely a design choice. I suggested above answer because the functionality is already provided all you need is to implement it according to your need. – Aniket Thakur Aug 22 '13 at 06:43
1

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

Community
  • 1
  • 1
Alexis
  • 404
  • 1
  • 3
  • 10
1

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

Naresh Joshi
  • 4,188
  • 35
  • 45