3

我正在开发一个 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());

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

4

1 回答 1

6

这个想法是有一个受保护的虚拟方法clone_implBase一个公共的非虚拟方法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());
    }
};
于 2013-03-22T16:30:29.877 回答