When programming C++ we used to create copy constructors when needed (or so we were taught). When switching to Java a few years ago, I noticed that the Cloneable interface is now being used instead. C# followed the same route defining the ICloneable interface. It seems to me that cloning is part of the definition of OOP. But I wonder, why were these interfaces created, and the copy constructor seems to have been dropped?
When I thought about it, I came to the thought that a copy constructor would not be useful if one needs to make a copy of an object whose type is not known (as in having a reference to a base type). This seems logical. But I wonder whether there are other reasons that I do not know of, for which the Cloneable interfaces have been favored over copy constructors?
Cloneable interface is implemented by a class to make Object. clone() method valid thereby making field-for-field copy. This interface allows the implementing class to have its objects to be cloned instead of using a new operator.
The Cloneable interface itself is empty; it is just a marker interface used by Java to ensure that using the clone method is legal. Doing it this way also removes the ability to make use of generics to ensure type safety: class Foo implements Cloneable { // Valid.
Object's clone() method probably just checks it using: this instanceof Cloneable. The reason that the clone() method is defined in the Object class, is because some 'magic' is needed to actually make a clone. First of all, a new object has to be created without the use of a constructor.
Cloneable interface must be implemented by the class whose object clone we want to create. If we don't implement Cloneable interface, clone() method generates CloneNotSupportedException. The clone() method is defined in the Object class.
I think it's because there is no such inherent need for a copy constructor in Java and in C# for reference types. In C++ objects are named. You can (and you will most often) copy (and in C++1x move) them around e.g when returning from functions, since returning pointers require you to allocate dynamic memory which would be slow and painful to manage. The syntax is T(x) so it makes sense to make a constructor taking a T reference. C++ couldn't make a clone function, since that would require returning an object by value again (and thus another copy).
But in Java, objects are unnamed. There are only references to them, which can be copied, but the object itself isn't copied. For the cases when you actually need to copy them, you can use the clone call (but i read in other anwers clone is flawed. i'm no java programmer so i cannot comment that). Since not the object itself is returned, but rather a reference to it, a clone function will suffice. Also a clone function can be overriden. That's not going to work with copy constructors. And incidentally, in C++ when you need to copy a polymorphic object, a clone
function is required too. It's got a name, the so-called virtual copy constructor.
Because C++ and Java (and C#) aren't the same thing. C++ has no built-in interfaces because interfaces aren't part of the language. You can fake them with abstract classes but they aren't how you think about C++. Also, in C++ assignment is normally deep.
In Java and C# assignment just involves copying the handle to the internal object. Basically when you see:
SomeClass x = new SomeClass();
in Java or C#, there's a level of indirection builtin that doesn't exist in C++. In C++, you write:
SomeClass* x = new SomeClass();
Assignment in C++ involves the dereferenced value:
*x = *another_x;
In Java you can get access to the "real" object as there is no dereference operator like *x. So to do a deep copy, you need a function: clone(). And both Java and C# wrapped that function into an interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With