2016-07-25 5 views
1

이 질문이 전에 제기되었는지 확실하지 않습니다. 나는 factory 클래스를 구현 중이다. 모든 인스턴스는 기본 클래스 InstBase에서 상속해야하며 중앙 집중식 팩토리를 통해 초기화해야합니다. 이 예에서 볼 수 있듯이개인 초기화가있는 C++ 생성자

class InstBase { 
    friend class Factory;  

    private: 
    InstBase() = default; 
    factory* factory; 
} 


class Factory { 

    template <typename Derived, typename... ArgsT> 
    InstBase* get(ArgsT&&... args) { 
    return new Derived(std::forward<ArgsT>(args)...)      
    } 

} 

class MyInst : public InstBase { 
    public: 
    MyInst(int a, int b) {...}; 
} 

factory.get<MyInst>(1, 2); 

는, 인터페이스는 템플릿으로 Derived 소요 Derived의 생성자에 전달 사용자 정의 인수 목록과 인스턴스를 초기화합니다. 그러나 여기에 추가하려는 것은 인스턴스가 작성된 팩토리에 포인터를 지정하는 것입니다.

template <typename Derived, typename... ArgsT> 
    InstBase* get(ArgsT&&... args) { 
    auto ptr = new Derived(std::forward<ArgsT>(args)...); 
    ptr->factory = this; 
    return ptr;      
    } 

내가 파생 만 공장 클래스 newed하기 전에 기본 클래스 InstBase는 항상 생성되기 때문에이 조금 중복 느낌 :에 의해이 수행 할 수 있습니다. get의 인터페이스를 변경하지 않고이 목표를 달성하기위한 트릭이 있습니까? 인수 목록에 factory에 다른 포인터를 부착하도록 사용자에게 요청하는 것은 의미가 없습니다 (예 : factory.get<MyInst>(1, 2, &factory)). 그것은 다음과 같이

template<typename> 
constexpr bool isBaseOf() { return false; } 

template<typename T, typename U, typename... O> 
constexpr bool isBaseOf() { return std::is_base_of<T, typename std::decay<U>::type>::value || isBaseOf<T, O...>(); } 

는 따라서 공장 출하 방법을 변경 : 당신이 인수의 유형으로 Factory의 사용을 금지 할 경우

+0

당신의 예제 코드는 :'ptr-> factor = this;'괜찮아 보인다.'get'에서'factory'가 필요 없다. – marcinj

+0

여기를 참조하십시오 : http://coliru.stacked-crooked.com/a/c05ab3123f168f91 – marcinj

+0

'get 인터페이스를 변경하지 않고이 목표를 달성하려면 어떤 트릭이 있습니까? '** 목표는 정확히 무엇입니까 **? 당신의 제안은'get'의 인터페이스를 변경하는 것으로 보이지 않습니다. – user2079303

답변

0

, 당신은이 같은 (C++ 11 호환)를 사용할 수 있습니다 :

template <typename Derived, typename... ArgsT> 
InstBase* get(ArgsT&&... args) { 
    static_assert(not isBaseOf<Factory, ArgsT...>(), "!"); 
    return new Derived(std::forward<ArgsT>(args)...)      
} 

그렇긴해도, 내가 원하는 매개 변수를 사용하지 못하게하는 수업을 사용하지 않기 때문에 나는 너무 좋아하지 않는다 !!