Implementing the Clone () Method in the Base Class
Here's the implementation Clone()
for my class:
MyClass^ Clone(){
return gcnew MyClass(this->member1, this->member2);
}
Now I have about 10 classes derived from MyClass
. The implementation is the same in each case. Due to the fact that I need to call gcnew
with the actual class name in each case, I need to create 10 almost identical implementations Clone()
.
Is there a way to write one single method Clone()
in the base class that will serve all 10 derived classes?
Edit: Is there a way to call the constructor of a class through one of its objects? In a way that will refer to the actual constructor of the derived class. Sort of:
MyClass ^obj2 = obj1->Class->Construct(arg1, arg2);
I am doing this in C ++ / CLI, but answers from other languages ββare welcome.
a source to share
In plain old C ++, you can do this with compile-time polymorphism (curiously repeating template pattern). Assuming your derived classes are copyable, you can simply write:
class Base
{
public:
virtual Base* Clone() const = 0;
//etc.
};
template <typename Derived>
class BaseHelper: public Base
{
//other base code here
//This is a covariant return type, allowed in standard C++
Derived * Clone() const
{
return new Derived(static_cast<Derived *>(*this));
}
};
Then use it like:
class MyClass: public BaseHelper<MyClass>
{
//MyClass automatically gets a Clone method with the right signature
};
Note that you cannot checkout and work with the class again without problems - you need to "think" about how to be able to re-template intermediate classes or restart Clone
again.
a source to share
I think you can use the Factory pattern here. I.e:.
MyClass Clone(){
return MyClassFactory.createInstance(this.getClass(), this.member1, this.member2, ...);
}
In a factory, you need to instantiate a subclass based on the passed class type. It probably has the same disadvantages as your approach.
a source to share
I would suggest using copy constructors instead (since derived classes can also call the base implementation's copy constructor) - also handy, since this would be familiar territory for C ++ programmers.
You might be able to create a single Clone method that uses reflection to call the copy constructor itself on that instance.
It might also be worth noting what Jeffrey Richter said in his book Frame Design Guides: βThe ICloneable interface is an example of a very simple abstraction with a contract that has never been explicitly documented. Some types implement this interface Clone
so that it makes a shallow copy of the object. while some implementations do a deep copy. Since the method of this interface Clone
should never have been fully documented, when using an object with a type that implements ICloneable
, you never know that you This makes the interface useless "(emphasis mine)
a source to share