2017-05-22 6 views
0

MWE는 꽤 길기 때문에 나와 함께하시기 바랍니다. 요약하자면, 추상 객체 팩토리를 사용하여 기본 클래스에서 파생 된 객체를 작성하고, 파생 객체를 싱글 톤으로 만들고 shared_ptr을 사용하여 전달합니다. 싱글 톤 템플릿을 제외하고 싱글 톤이 파생되지 않은 경우 지금까지 모든 것이 정상적으로 작동합니다.C++ 11 추상 팩토리를 가진 파생 클래스의 싱글 톤

의 하나는 다음과 같은 구조를 가지고 가정 해 봅시다 :

class Base{} 
class Derived1 : public Base {} // public Base, public Singleton<Derived1> 
class Derived2 : public Base {} 

내가 파생 클래스를 생성하는 내 추상적 인 객체 팩토리를 사용하지만, 한 번만 생성되었는지 확인하고 다른 성병 :: shared_ptr의를 반환하고 싶습니다 파생 된 개체에.

나는 싱글 템플릿과 난 아무것도에서 파생되지 않은 개체를 만들려면 잘 작동 객체 팩토리를 구현 한 :

싱글 톤 :

template<class Derived> 
class Singleton{ 
    private: 
    static std::shared_ptr<Derived> instance_; 
    public: 
    template <typename... Args> 
     static 
     std::shared_ptr<Derived> Instance(Args... args){ 
     if (instance_ == nullptr){ 
      instance_ = std::shared_ptr<Derived>(
       new Derived(std::forward<Args>(args)...)); 
     } 
     return instance_; 
     } 
}; 
template <class T> std::shared_ptr<T> Singleton<T>::instance_ = nullptr; 

개체 공장 :

:
template <class Object, typename... Args> 
class Abstract_Factory_Base { 
    protected: 
    using Factories_Map = std::unordered_map<std::string, std::shared_ptr<Abstract_Factory_Base<Object, Args... >> >; 
    static Factories_Map* factories_; ///< \brief stores factories able to construct objects derived from "Object" template parameter 

    public: 
    Factories_Map* factories(){ 
     if(factories_ == nullptr){ 
      factories_ = new Factories_Map; 
     } 
     return factories_; 
    } 

    static 
    std::shared_ptr<Abstract_Factory_Base<Object, Args...>> 
    Type(const std::string &key){ 
     return (*factories_)[key]; 
    }; 

    virtual 
    std::shared_ptr<Object> 
    create(const Args &... args) = 0; 

}; 


template <class Object, class Derived, typename... Args> 
class Abstract_Factory : public Abstract_Factory_Base<Object, Args...>{ 
    public: 
    std::shared_ptr<Object> 
     create(const Args &... args){ 
     return std::shared_ptr<Derived>(
       new Derived(args...)); 
    } 
}; 
template <class Object, class Derived, typename... Args> 
class Factory_Register : public Abstract_Factory<Object, Derived, Args...>{ 
    public: 
    Factory_Register(const std::string& key){ 
    //static_assert(!(std::is_base_of<Singleton<Derived>, Derived>::value), ""); 
     this->factories()->emplace(
       key, 
       std::shared_ptr<Abstract_Factory_Base<Object, Args...>>(
         new Abstract_Factory<Object, Derived, Args...>)); 
    } 
}; 

template <class Object, class Derived, typename... Args> 
class Singleton_Factory : public Abstract_Factory_Base<Object, Args...>{ 
    public: 
    std::shared_ptr<Object> create(const Args &... args){ 
     return Derived::Instance(args...); 
    } 
}; 
template <class Object, class Derived, typename... Args> 
class Singleton_Factory_Register : public Singleton_Factory<Object, Derived, Args...>{ 
    public: 
    Singleton_Factory_Register(const std::string& key){ 
     //static_assert(std::is_base_of<Singleton<Derived>, Derived>::value, ""); 
     this->factories()->emplace(
       key, 
       std::shared_ptr<Abstract_Factory_Base<Object, Args...>>(
         new Singleton_Factory<Object, Derived, Args...>)); 
    } 
}; 

내가 지금 함께 사용하고 싶은 말은하자3210

나는 지난 시간 이후로 해결할 수없는 움직임에 대해 불평하는 많은 편집 오류를 얻습니다.

나를 도와 주시겠습니까, 아니면 다른 곳으로 리디렉션 할 수 있습니까? 적어도 내가 가능하기를 바랄까? 감사!

In file included from /usr/include/c++/5/bits/shared_ptr.h:52:0, 
       from /usr/include/c++/5/memory:82, 
       from main.cpp:2: 
/usr/include/c++/5/bits/shared_ptr_base.h: In instantiation of ‘std::__shared_ptr<_Tp, _Lp>& std::__shared_ptr<_Tp, _Lp>::operator=(std::__shared_ptr<_Tp1, _Lp>&&) [with _Tp1 = Abstract_Factory_Base<Foo, int, int>; _Tp = FooFoo; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’: 
/usr/include/c++/5/bits/shared_ptr.h:302:4: required from ‘std::shared_ptr<_Tp>& std::shared_ptr<_Tp>::operator=(std::shared_ptr<_Tp1>&&) [with _Tp1 = Abstract_Factory_Base<Foo, int, int>; _Tp = FooFoo]’ 
main.cpp:180:13: required from here 
/usr/include/c++/5/bits/shared_ptr_base.h:1008:4: error: no matching function for call to ‘std::__shared_ptr<FooFoo, (__gnu_cxx::_Lock_policy)2u>::__shared_ptr(std::remove_reference<std::__shared_ptr<Abstract_Factory_Base<Foo, int, int>, (__gnu_cxx::_Lock_policy)2u>&>::type)’ 
    __shared_ptr(std::move(__r)).swap(*this); 
    ^
/usr/include/c++/5/bits/shared_ptr_base.h:1146:7: note: candidate: std::__shared_ptr<_Tp, _Lp>::__shared_ptr(const std::__weak_ptr<_Tp, _Lp>&, std::nothrow_t) [with _Tp = FooFoo; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u] 
     __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t) 
    ^
/usr/include/c++/5/bits/shared_ptr_base.h:1146:7: note: candidate expects 2 arguments, 1 provided 
/usr/include/c++/5/bits/shared_ptr_base.h:1094:2: note: candidate: template<class _Alloc, class ... _Args> std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) 
    __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, 
^
/usr/include/c++/5/bits/shared_ptr_base.h:1094:2: note: template argument deduction/substitution failed: 
/usr/include/c++/5/bits/shared_ptr_base.h:1008:4: note: cannot convert ‘std::move<std::__shared_ptr<Abstract_Factory_Base<Foo, int, int>, (__gnu_cxx::_Lock_policy)2u>&>((* & __r))’ (type ‘std::remove_reference<std::__shared_ptr<Abstract_Factory_Base<Foo, int, int>, (__gnu_cxx::_Lock_policy)2u>&>::type {aka std::__shared_ptr<Abstract_Factory_Base<Foo, int, int>, (__gnu_cxx::_Lock_policy)2u>}’) to type ‘std::_Sp_make_shared_tag’ 
    __shared_ptr(std::move(__r)).swap(*this); 

답변

0

나는 문제가 foofoo1 = Foo_Factory::Type("foofoo") 당신이 std::shared_ptr<FooFoo> 하나에 유형 std::shared_ptr<Abstract_Factory_Base<Foo,int,int>>의 객체를 할당하려고한다는 것입니다 생각합니다. 이러한 유형 간에는 변환이 없습니다. create에 전달되는 FooFoo 생성자에 대한 적절한 매개 변수를

foofoo1 = Foo_Factory::Type("foofoo")->create(...); 

:

는이 문제를 해결하려면, 당신은 당신이 저장할 개체를 만드는 데 반환 팩토리 객체를 사용해야합니다.

+0

안녕하세요 "* FooFoo에 푸 *에서 변환 할 수 없습니다

따라서, 오류가 주요 인 (foo_Factory :: Type ("foofoo")'만이 괜찮은지 컴파일했는지 확인하고 싶었습니다.) 이 foofoo1 = Foo_Factory :: Type ("foofoo") -> create (1,2);하지만 실패합니다 .μ – Napseis

0

좋아, 나는 그런 디자인에 관심이있는 사람들을 위해 마침내 관리했다. 내가 대신 스마트 것들의 사용 원시 포인터를 발견하고 난 간단한 오류 메시지를 받았습니다 :.

std::shared_ptr<Foo> foofoo1, foofoo2, foofoo3; 
// Pointer on base class Foo of course !