Как использовать clone () в C ++ с множественным наследованием абстрактных классов?

Я работаю над программой на C ++, но у меня возникают проблемы с множественным наследованием при использовании клонирования. Проблема (в упрощенном виде) заключается в следующем.

Я хочу иметь возможность клонировать все объекты, полученные из класса Base.

class Base{
public:

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

Я хочу определить два других класса, производных от Base, которые оба являются абстрактными, то есть я не могу определить функцию клона, но я должен объявить их некоторым образом (я хочу убедиться, что если я клонирую Derived *, я получу назад производные * а не базовые *, т.е. я хочу избежать кастинга в точке приложения)

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». Если я объявляю clone () в Derived1 и Derived2 не чисто виртуальным, но без определения, ошибка остается той же:

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

Если у кого-то есть идея или решение, я буду признателен за это!

2

Решение

Идея состоит в том, чтобы иметь защищенный виртуальный метод clone_impl в Base и публичный не виртуальный 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());
}
};
2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector