2

私の現在のプロジェクトでは、ポリモーフィックboost::ptr_vectorに保持するために を使用していますが、ObjectsVS2010 ビルドの 1 つが を複製できないとスローするまで、すべて正常に機能していobjectましたnew_clone()c++ FAQはそれを作成しましboostたが、現在、VS2010 は、抽象クラスでクローンを使用できないと言って、この shanagin を私に投げかけています。pure virtual

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>          ]

これは、boost でクローンを作成できるようにするには、抽象基本クラスを破棄する必要があるということですか?


ノート:

  • 抽象基本クラスのオブジェクトがプログラムに存在することは決してありませんが、ほとんどすべてがそのように扱われます。
  • クローンメソッドを非仮想にし、実際に何かを返す手段を与えると(コンストラクター/コピーコンストラクターを提供します。これは、設計に反する存在する可能性があることを意味します)、コンパイラーは、すべての派生クラスにデフォルトのコンストラクタ。それらを持たないのは設計によるものです。

編集:私は実装していません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;
};
4

1 に答える 1

3

new_clone()必要なのは、Boostの関数よりもコンパイラーによって取得される独立した(非メンバーの)関数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();
}
于 2012-05-07T01:20:48.570 に答える