Копирование полиморфного объекта в С++
У меня есть базовый класс Base
, из которого выведены Derived1
, Derived2
и Derived3
.
Я построил экземпляр для одного из производных классов, который я сохраняю как Base* a
. Теперь мне нужно сделать глубокую копию объекта, который я буду хранить как Base* b
.
Насколько я знаю, обычным способом копирования класса является использование конструкторов копирования и перегрузка operator=
. Однако, поскольку я не знаю, имеет ли тип a
тип Derived1
, Derived2
или Derived3
, я не могу придумать способ использования либо конструктора копирования, либо operator=
. Единственный способ, я могу придумать, чтобы сделать эту работу, - это реализовать что-то вроде:
class Base
{
public:
virtual Base* Clone() = 0;
};
и реализация Clone
in в производном классе, как в:
class Derivedn : public Base
{
public:
Base* Clone()
{
Derived1* ret = new Derived1;
copy all the data members
}
};
Java, как правило, использует Clone
, может быть, существует больше возможностей С++ для этого?
Ответы
Ответ 1
Это все еще, как мы делаем материал в С++ для полиморфных классов, но вам не нужно делать явную копию членов, если вы создаете конструктор копирования (возможно неявный или закрытый) для ваших объектов.
class Base
{
public:
virtual Base* Clone() = 0;
};
class Derivedn : public Base
{
public:
//This is OK, its called covariant return type.
Derivedn* Clone()
{
return new Derivedn(*this);
}
private:
Derivedn(const Derivedn) : ... {}
};
Ответ 2
template <class T>
Base* Clone (T derivedobj) {
T* derivedptr = new T(derivedobj);
Base* baseptr = dynamic_cast<Base*>(derivedptr);
if(baseptr != NULL) {
return baseptr;
}
// this will be reached if T is not derived from Base
delete derivedptr;
throw std::string("Invalid type given to Clone");
}
Единственное, что требуется этой функции для производных классов, это то, что их конструктор копирования общедоступен.