У меня проблема с клонируемыми абстрактными классами и уникальными указателями. Предположим, что у меня есть следующий Клонируемый абстрактный базовый классКлонируемая иерархия классов и unique_ptr
class Base
{
public:
virtual void doSomething()=0;
virtual std::unique_ptr<Base> clone() const=0;
}
и производный абстрактный класс, который обеспечивает дополнительный способ
class Derived : public Base
{
public:
virtual void doSomething()=0;
virtual void doSomethingMore()=0;
virtual std::unique_ptr<Base> clone() const=0;
}
Это позволяет определить новые классы, которые хранят полиморфный объект иерархии базы по составу , Например
class Composed
{
public:
Composed(Base const &base_) : basePtr(base_.clone()) {}
private:
std::unique_ptr<Base> basePtr;
}
В этом случае я должен быть в состоянии хранить объект типа Derived в Состоящем, без нарезки методы, которые производные добавляют WRT Base. Однако я хотел бы определить другой объект, который хранит полиморфный объект, который наследует Derived, рассматривая его как объект типа Derived. Используя ту же структуру, что и выше
class ComposedDerived
{
public:
ComposedDerived(Derived const &derived_) : derivedPtr(derived_.clone()) {}
private:
std::unique_ptr<Derived> derivedPtr;
}
Очевидно, я получаю ошибку компиляции, так как метод клонирования производных возвращает std::unique_ptr<Base>
. С другой стороны, если я изменить определение производного следующего
class Derived : public Base
{
public:
virtual void doSomething()=0;
virtual void doSomethingMore()=0;
virtual std::unique_ptr<Derived> clone() const=0;
}
В этом случае компилятор выдает следующую ошибку: invalid covariant return type for ‘virtual std::unique_ptr<Derived> Derived::clone() const
.
Есть ли способ для компилятора, чтобы понять, что std::unique_ptr<Derived>
на самом деле может быть использован в качестве std::unique_ptr<Base>
через полиморфизм и не спорьте о типе возвращаемого производного класса clone
метода?
Как насчет 'производныйPtr (static_cast (производный_.clone(). Release()))'? –
Это кажется разумным способом сделать это. Не могли бы вы объяснить '.release()'? Из того, что я понимаю, 'output_.clone()' возвращает объект 'std :: unique_ptr '. '.release()' let this unique_ptr освобождает право собственности на объект 'Derived', который был создан в куче и возвращает объект' Base * '. Наконец, я навел этот указатель на указатель 'Derived *', который используется для инициализации 'производногоPtr'. Это верно? –