2012-05-07 2 views
2

для моего текущего проекта я использую boost::ptr_vector держать Objects полиморфно, и все это было прекрасно работать, пока один из моих строит VS2010 бросок, что он не смог клонировать object поэтому я пошел , и искал клонирование, и реализовал метод new_clone() по просьбе boost, а затем c++ FAQ сделал его pure virtual, но теперь VS2010 бросает этот шанагин на меня, говоря, что он не может использовать клон в абстрактном классе.Clone распределители и полиморфизм в повышении :: ptr_container

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 не виртуальным и предоставляю ему средство для фактического возврата чего-либо (предоставление конструктора/копии конструктора, что означает, что они могут существовать, что противоречит дизайну), тогда компилятор бросает все классам нужен конструктор по умолчанию. которые не имеют их по дизайну.

EDIT: Я не реализовать 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

Можете ли вы показать нам 'Object' определение? В частности, область вокруг 'Object.h (36)'? Кроме того, можете ли вы показать нам свои определения функций 'new_clone' и' delete_clone'? –

+0

@NicolBolas см. В редакции – gardian06

ответ

3

Что вы хотите свободно стоящая (не -Член) new_clone() функция, которая будет получать подобран компилятором в предпочтении к одному в подталкивания-х 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(); 
} 
+0

Я тоже делаю подобное для производных классов (хотя их методы клонирования фактически имеют реализации), или это просто для «абстрактного базового класса». – gardian06

+2

@ gardian06: Это просто тип, который вы передаете 'ptr_vector'. Если вам нужно делать вещи, специфичные для производного типа, предполагается, что у вас будет какая-то виртуальная (возможно, чистая) функция-член, которая выполняет настоящую работу. Это простой крючок, так что вы не должны создавать функции-члены с определенным именем. Таким образом, если у вас уже есть клонирование по другим причинам, глобальный крючок позволит использовать 'ptr_vector'. –

+0

Просто добавьте к тому, что сказал Никол: виртуальная функция 'do_clone()' должна быть реализована в каждом производном классе для выполнения реальной работы клонирования экземпляра. Эта функция, не являющаяся членом, «отбрасывает» виртуальную функцию. –