3

私は C++ プログラムに取り組んでいますが、複製を使用するときに多重継承に問題があります。問題は(簡略化された形式で)次のとおりです。

クラス Base から派生したすべてのオブジェクトを複製できるようにしたいと考えています。

class Base{
public:

    virtual Base* clone()const=0;
};

Base から派生した他の 2 つのクラスを定義したいのですが、どちらも抽象的です。つまり、クローン関数を定義できませんが、何らかの方法でそれらを宣言する必要があります (Derived* をクローンすると、 back 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 の両方から継承される 4 番目のクラスを宣言すると、問題が発生します。

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に、クラスがabstractではなく、すべての派生クラスの非仮想ラッパー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 に答える