Как писал Скотт Майерс, вы можете воспользоваться расслаблением в системе типов C ++, чтобы объявить 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, чтобы сохранить их в производном указателе, если он им нужен.
Является ли один из этих подходов предпочтительным? Или у меня есть способ съесть мою семантику перехода права собственности и иметь сильную безопасность типов?