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.

0


a source to share


4 answers


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.

+3


a source


Not in C ++ that I am aware of. As you say, you need to create an object of a different class in each Clone () implementation.



0


a source


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.

0


a source


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)

0


a source







All Articles