Как написал Скотт Майерс, вы можете воспользоваться расслаблением в С++-типе-системе, чтобы объявить clone(), чтобы вернуть указатель на текущий тип объявления:
class Base
{
virtual Base* clone() const = 0;
};
class Derived : public Base
{
virtual Derived* clone() const
};
Компилятор обнаруживает, что clone() возвращает указатель на тип объекта и позволяет Derived переопределять его, чтобы вернуть указатель на производный.
Желательно, чтобы clone() возвращал интеллектуальный указатель, который подразумевает передачу семантики собственности, например:
class Base
{
virtual std::auto_ptr<Base> clone() const = 0;
};
class Derived : public Base
{
virtual std::auto_ptr<Derived> clone() const;
};
К сожалению, релаксация соглашений не применяется к шаблонным интеллектуальным указателям, и компилятор не допустит переопределение.
Итак, кажется, у меня осталось два варианта:
- Имейте clone() верните указатель "немой" и запишите, что клиенты несут ответственность за его удаление.
- Имейте clone() верните умный базовый указатель и попросите клиентов использовать dynamic_cast для сохранения их в указателе Derived, если это необходимо.
Является ли один из этих подходов предпочтительным? Или у меня есть способ съесть мою передачу семантики собственности и у меня тоже сильная безопасность?