Копирование полиморфного объекта в C ++ - PullRequest
34 голосов
/ 01 марта 2011

У меня есть базовый класс Base, из которого происходит Derived1, Derived2 и Derived3.

Я создал экземпляр для одного из производных классов, который я храню как Base* a. Теперь мне нужно сделать глубокую копию объекта, который я буду хранить как Base* b.

Насколько я знаю, обычный способ копирования класса заключается в использовании конструкторов копирования и перегрузке operator=. Однако, поскольку я не знаю, относится ли a к типу Derived1, Derived2 или Derived3, я не могу придумать, как использовать конструктор копирования или operator=. Единственный способ, которым я могу придумать, чтобы сделать эту работу чисто, - реализовать что-то вроде:

class Base
{
public:
  virtual Base* Clone() = 0;

};

и агрегат Clone в производном классе, как в:

class Derivedn : public Base
{
public:
  Base* Clone() 
  {
    Derived1* ret = new Derived1;
    copy all the data members
  }
};

Java имеет тенденцию использовать Clone довольно много, есть ли больше C ++ способ сделать это?

Ответы [ 2 ]

35 голосов
/ 01 марта 2011

Это все еще то, как мы делаем вещи в C ++ для полиморфных классов, но вам не нужно делать явную копию членов, если вы создаете конструктор копирования (возможно, неявный или частный) для ваших объектов.*

2 голосов
/ 04 мая 2017
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");
}

Единственное, что эта функция требует от производных классов, - это то, что их конструктор копирования является общедоступным.

...