0

这是Clone()我的班级的一个实现:

    MyClass^ Clone(){
        return gcnew MyClass(this->member1, this->member2);
    }

现在我有大约 10 个类派生自MyClass. 每种情况下的实现都是相同的。由于gcnew在每种情况下我都需要使用实际的类名进行调用,因此我需要创建 10 个几乎相同的Clone().

Clone()有没有办法在基类中编写一个方法来服务所有 10 个派生类?

编辑:有没有办法通过其中一个对象调用类的构造函数?以某种方式调用实际的派生类构造函数。就像是:

MyClass ^obj2 = obj1->Class->Construct(arg1, arg2);

我在 C++/CLI 上执行此操作,但欢迎使用其他语言的答案。

4

4 回答 4

4

在普通的旧 C++ 中,您可以使用编译时多态性(奇怪地重复出现的模板模式)来做到这一点。假设您的派生类是可复制的,您可以编写:


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));
    }
};

然后像这样使用它:


class MyClass: public BaseHelper<MyClass>
{
    //MyClass automatically gets a Clone method with the right signature
};

请注意,您不能再次从类派生并使其无缝工作 - 您必须“设计”选项以通过模板中间类再次派生,或者重新开始重写Clone

于 2009-05-19T12:46:13.557 回答
0

我建议改用复制构造函数(因为派生类也可以调用基实现的复制构造函数)——也很方便,因为它是 C++ 程序员熟悉的领域。

在此实例中,您也许可以创建一个使用反射调用自身复制构造函数的克隆方法。

可能还值得注意的是,Jeffrey Richter 在《框架设计指南》一书中说:“ICloneable 接口是一个非常简单的抽象示例,它带有一个从未明确记录过的契约。某些类型实现了这个接口的Clone方法,以便它执行一个浅拷贝对象,而一些实现执行深度复制。因为这个接口的Clone方法应该做的事情从来没有完全记录,当使用具有实现类型的对象时ICloneable,你永远不知道你会得到什么。这使得接口无用“ (强调我的)

于 2009-05-19T12:27:57.553 回答
0

不是我知道的C++。正如您所说,您需要在 Clone() 的每个实现中创建不同类的对象。

于 2009-05-19T12:12:09.677 回答
0

嗯,我想你可以在这里使用工厂模式。IE:

MyClass Clone(){
    return MyClassFactory.createInstance(this.getClass(), this.member1, this.member2, ...);
}

在工厂中,您必须根据传递的类类型创建子类的实例。因此,它可能与您的方法具有相同的缺点。

于 2009-05-19T12:19:19.693 回答