Ваш последний пример, ...
Food* food1 = dynamic_cast<Food*>(apple1);
Apple* clone2 = f1->clone();
... не будет работать, даже если исправлена ошибка орфографии. Вам нужен актерский состав другим способом:
Food* food1 = apple1;
Apple* clone2 = dynamic_cast<Apple*>( f1->clone() );
Кроме того, практическим решением клонирования в C ++ является определение макроса:
#define YOURPREFIX_IMPLEMENT_CLONING( Class ) \
virtual Class* \
virtualCloneThatIsUnsafeToCallDirectly() const \
{ \
assert( typeid( *this ) == typeid( Class ) ); \
return new Class( *this ); \
} \
\
OwnershipPtr< Class > \
clone() const \
{ \
return OwnershipPtr< Class >( \
virtualCloneThatIsUnsafeToCallDirectly() \
); \
}
... где OwnershipPtr
может быть, например, std::auto_ptr
.
Тогда все, что вам нужно сделать, это поместить вызов макроса в каждый класс, который должен поддерживать клонирование. Простой.
Также возможно реализовать многоразовое клонирование с помощью шаблонов, но это сложнее как для реализации, так и для использования. Вы можете прочитать об этом в моем блоге "3 способа смешивания в общей реализации клонирования" . Вывод, однако, заключается в том, что макрос является наиболее практичным.