Распределители клонов и полиморфизм в boost::ptr_container
Для моего текущего проекта я использую boost::ptr_vector
держать Objects
полиморфно, и все это работало нормально, пока одна из моих сборок VS2010 не выбросила, что она не смогла клонировать object
поэтому я пошел, посмотрел клонирование и реализовал new_clone()
метод по запросу boost
и следовал C++ FAQ сделал это pure virtual
, но теперь VS2010 бросает мне этот шанагин, говоря, что он не может использовать клон в абстрактном классе.
1>c:\program files\boost\boost_1_49_0\boost\ptr_container\clone_allocator.hpp(34): error C2259: 'Object' : cannot instantiate abstract class
1> due to following members:
1> 'Object *Object::new_clone(void) const' : is abstract
1> c:\...\Object.h(36) : see declaration of 'Object::new_clone'
1> c:\program files\boost\boost_1_49_0\boost\ptr_container\clone_allocator.hpp(68) : see reference to function template instantiation 'T *boost::new_clone<U>(const T &)' being compiled
1> with
1> [
1> T=Object,
1> U=Object
1> ]
1> c:\program files\boost\boost_1_49_0\boost\ptr_container\detail\reversible_ptr_container.hpp(110) : see reference to function template instantiation 'U *boost::heap_clone_allocator::allocate_clone<Object>(const U &)' being compiled
1> with
1> [
1> U=Object
1> ]
1> c:\program files\boost\boost_1_49_0\boost\ptr_container\detail\reversible_ptr_container.hpp(99) : while compiling class template member function 'Object *boost::ptr_container_detail::reversible_ptr_container<Config,CloneAllocator>::null_clone_allocator<allow_null_values>::allocate_clone(const Object *)'
1> with
1> [
1> Config=boost::ptr_container_detail::sequence_config<Object,std::vector<void *,std::allocator<void *>>>,
1> CloneAllocator=boost::heap_clone_allocator,
1> allow_null_values=false
1> ]
1> c:\program files\boost\boost_1_49_0\boost\ptr_container\detail\reversible_ptr_container.hpp(276) : see reference to class template instantiation 'boost::ptr_container_detail::reversible_ptr_container<Config,CloneAllocator>::null_clone_allocator<allow_null_values>' being compiled
1> with
1> [
1> Config=boost::ptr_container_detail::sequence_config<Object,std::vector<void *,std::allocator<void *>>>,
1> CloneAllocator=boost::heap_clone_allocator,
1> allow_null_values=false
1> ]
1> c:\program files\boost\boost_1_49_0\boost\ptr_container\detail\reversible_ptr_container.hpp(275) : while compiling class template member function 'void boost::ptr_container_detail::reversible_ptr_container<Config,CloneAllocator>::null_policy_deallocate_clone(const Object *)'
1> with
1> [
1> Config=boost::ptr_container_detail::sequence_config<Object,std::vector<void *,std::allocator<void *>>>,
1> CloneAllocator=boost::heap_clone_allocator
1> ]
1> c:\program files\boost\boost_1_49_0\boost\ptr_container\ptr_sequence_adapter.hpp(132) : see reference to class template instantiation 'boost::ptr_container_detail::reversible_ptr_container<Config,CloneAllocator>' being compiled
1> with
1> [
1> Config=boost::ptr_container_detail::sequence_config<Object,std::vector<void *,std::allocator<void *>>>,
1> CloneAllocator=boost::heap_clone_allocator
1> ]
1> c:\program files\boost\boost_1_49_0\boost\ptr_container\ptr_vector.hpp(35) : see reference to class template instantiation 'boost::ptr_sequence_adapter<T,VoidPtrSeq,CloneAllocator>' being compiled
1> with
1> [
1> T=Object,
1> VoidPtrSeq=std::vector<void *,std::allocator<void *>>,
1> CloneAllocator=boost::heap_clone_allocator
1> ]
1> c:\general\dev\senior\tankbattle3d\tankbattle3d\tankbattle3d\room.h(28) : see reference to class template instantiation 'boost::ptr_vector<T>' being compiled
1> with
1> [
1> T=Object
1> ]
Означает ли это, что для повышения способности клонировать вещи я должен выбросить абстрактный базовый класс?
ЗАМЕТКИ:
- Никогда не должен существовать объект абстрактного базового класса в программе, но почти все будет рассматриваться как таковое.
- Когда я делаю метод clone не виртуальным и даю ему средство для фактического возврата чего-либо (предоставляя конструктор / конструктор копирования, который будет означать, что они могут существовать, что противоречит дизайну), тогда компилятор выдает, что все классы dirived нуждаются в конструктор по умолчанию. который не имея их по замыслу.
РЕДАКТИРОВАТЬ: я не реализую delete_clone()
(не знал, что это было явно необходимо, и я думаю, что деструктор подойдет)
class Object{
public :
ObjectType superType;
bool toBeRemoved;
virtual void performAction(int action, Object& source){}
virtual void updateObject(float duration){}
virtual ~Object(){}
virtual Object * new_clone(void)const = 0; // Object.h[36]
bool operator==(const Object& _other)const;
bool operator!=(const Object& _other)const;
};
1 ответ
То, что вы хотите, это отдельностоящий (не член) new_clone()
функция, которая будет выбрана компилятором вместо той, что в Boost's clone_allocator.hpp
:
class Object{
public :
ObjectType superType;
bool toBeRemoved;
virtual void performAction(int action, Object& source){}
virtual void updateObject(float duration){}
virtual ~Object(){}
bool operator==(const Object& _other)const;
bool operator!=(const Object& _other)const;
private:
virtual Object * do_clone() const = 0;
};
// in the same namespace as `class Object`:
// so it will get picked up instead of Boost's default
// implementation
inline
Object* new_clone( const Object& o)
{
return o.do_clone();
}