如何在c++中对抽象类的多重继承使用clone()

How to use clone() in C++ with multiple inheritance of abstract classes?

本文关键字:多重继承 clone 抽象类 c++      更新时间:2023-10-16

我正在编写一个c++程序,但是在使用克隆时我遇到了多重继承的问题。问题(简化形式)如下。

我希望能够克隆从类Base派生的所有对象。

class Base{
public:
    virtual Base* clone()const=0;
};

我想定义另外两个从Base派生的类,它们都是抽象的,也就是说,我不能定义克隆函数,但我必须以某种方式声明它们(我想确保,如果我克隆derived *,我将返回derived *而不是Base*,也就是说,我想避免在应用程序点进行强制转换)

class Derived1: public virtual Base{
public:
    virtual Derived1* clone()const=0;
};
class Derived2: public virtual Base{
public:
    virtual Derived2* clone()const=0;
};

问题来了,当我声明第四个类,它继承自Derived1和Derived2:

class Derived3: public Derived1,public Derived2{
protected:
    int b;
public:
    Derived3():b(3){};
    Derived3(Derived3 const& l_B) {b=l_B.b;};
    virtual Derived3* clone()const{return new Derived3(*this);}
    ;
};

在这种情况下,我将从Visual c++ 2010编译器C2250中获得:'Derived3': 'Derived1 *Base::clone(void) const'的模糊继承。如果我在Derived1和Derived2中声明clone()不是纯虚拟的,但没有定义,错误仍然是相同的:

class Base{
public:
    virtual Base* clone()const=0;
};
class Derived1: public virtual Base{
public:
    virtual Derived1* clone()const;
};

class Derived2: public virtual Base{
public:
    virtual Derived2* clone()const;
};
class Derived3: public Derived1,public Derived2{
protected:
    int b;
public:
    Derived3():b(3){};
    Derived3(Derived3 const& l_B) {b=l_B.b;};
    virtual Derived3* clone()const{return new Derived3(*this);}
    ;
};

在Derived3中使用虚拟继承也没有帮助,我找不到解决它的方法,我只是想不出办法。很重要的一点是,所有的类都应该返回相同类型的指针,例如:我以后要这样做:

Derived3 test;
Derived1* test2=&test;
Derived1* test3=test2->clone();

和我要避免的:

Derived3 test;
Derived1* test2=&test;
Derived1* test3=dynamic_cast<Derived1*>(test2->clone());

如果有人有一个想法或解决方案,我将不胜感激!

这个想法是在Base中有一个受保护的虚拟方法clone_impl和一个公共的非虚拟方法clone:

class Base
{
protected:
    virtual Base* clone_impl() const = 0;
public:
    Base* clone() const
    {
      return clone_impl();
    }
};

每个派生类在不是抽象时提供clone_impl,并为所有派生类提供非虚拟包装器clone:

class DerivedX : ...
{
protected:
    // only when not abstract:
    virtual Base* clone_impl() const
    {
      return new DerivedX(*this);
    }
public:
    // in each derived class
    DerivedX* clone() const
    {
      return static_cast<DerivedX*>(clone_impl());
    }
};