1

Say we have a base class A which is abstract:

abstract class A {
  //code for class A
}

Also we have a subclass B which inherits from A and contains a copy constructor:

class B : A {

  //some other membervariables and methods  

  public B (B copy) {
    //makes a copy
  }
}

Now suppose we make a class GridObject which we want to inherit from A, and the grid elements it contains are also a type of A, but might be of type B or any other class that inherits from A:

class GridObject : A {
  A[,] grid;

  public GridObject (int columns, int rows) {
    grid = new A[columns, rows];
  }

  public GridObject (GridObject copy) {
    //makes a copy
  }

  public Add (A obj, int x, int y) {
    grid[x,y] = obj;
  }

Now, my problem is how to make a copy constructor that makes an exact copy of the GridObject. Suppose we do this:

B b = new B();
GridObject gridObject = new GridObject(5, 5);
for (int x = 0; x < 5; x++)
  for(int y = 0; y < 5; y++)
    gridObject.Add(new B (b), x, y);

Now, what is the best way to implement a (deep) copy constructor for the class GridObject? Note that the elements of our gridObject are of type B now. But this also might have been any other arbitrary class that inherits from A.

Quantum
  • 11
  • 1

2 Answers2

2

Look at implementing System.IConeable[1] in A, and then overriding this for each of the inheriting classes. Each class can then be responsible for knowing how to clone itself.

[1] http://msdn.microsoft.com/en-us/library/system.icloneable.aspx

Daniel Becroft
  • 716
  • 3
  • 19
0

For a generic deep copy helper method, see this SO question.

I'm not sure your classes should be responsible for making the copies though. Is there ever a chance a single object can be in two locations? Obviously I don't see the full implementation so I may be missing the use case, but I'd do something like this:

B b = new B();
GridObject gridObject = new GridObject(5, 5);
for (int x = 0; x < 5; x++)
  for(int y = 0; y < 5; y++)
    gridObject.Add(b.DeepClone(), x, y);

Note that I'm passing the copy into the constructor rather than relying on the constructor to make a copy for me.

Community
  • 1
  • 1
Chris
  • 4,393
  • 1
  • 27
  • 33
  • I see the usefulness of the DeepCopy() method here. It should work instead of a copy constructor. But I don't understand exactly how to implement this method in the program. And what should be extended and marked as [Serializable]? Say I want to clone the gridObject: `GridObject gridObjectCopy = gridObject.DeepCopy();` – Quantum Nov 10 '11 at 21:45
  • You'd add the Serializable attribute to your class. `[Serializable]class GridObject : A {...`. The linked question has a regular static method you can call and there's an [extension method](http://msdn.microsoft.com/en-us/library/bb383977.aspx) (used in my example). You can create a new static class ( called Utility for example) and paste that method into it. If you use the regular static version, you'd call it like `Utility.DeepClone(gridObject)`. If you use the extension method, you'd call it like `gridObject.DeepCopy()`. – Chris Nov 10 '11 at 21:50
  • I see, this would be a good solution for custom made classes while not using some other framework.. In my case this I'm using [XNA](http://create.msdn.com/en-US/), so it would not work, because it can't make a deep copy for objects like [Texture2D](http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.texture2d.aspx), because they are not marked as Serializable. I guess I should've mentioned that in the first place, sorry. – Quantum Nov 10 '11 at 22:21