2016-10-08 4 views
1

일반적으로, 오브젝트 팩토리는 클래스 Node가 기본 클래스 인 이와 같은 매개 변수없이 등록 기능 맵을 사용오브젝트 팩토리

auto world = ObjectFactory::instance()->create("MatrixTransform"); 
auto cube1 = ObjectFactory::instance()->create("Cube"); 
auto sphere = ObjectFactory::instance()->create("Sphere"); 

호출하여 클래스의 인스턴스를 생성 클래스 MatrixTransform, CubeSphere : 지금

// Map of registered factory functions 
std::map<std::string, std::function<Node *(void)>> functionRegistry; 

는 I 과부하 파라미터 제한된 수 복용 생성자 (하나 또는 2)과 같은 MatrixTransform(std::string objectName) 등록하고자 또는 MatrixTransform(std::string objectName, glm::mat4 matrixTransform), 그래서 내가 호출 할 수 있습니다뿐만 아니라

auto world = ObjectFactory::instance()->create("MatrixTransform"); 

뿐만 아니라

auto world = ObjectFactory::instance()->create("MatrixTransform", "world"); 

와 내가 다른 서명을 갖는지도 기능에 저장할 수 있습니다 알고도

auto world = ObjectFactory::instance()->create("MatrixTransform", "world", "glm::mat4())"); 

의미 서로 다른 매개 변수 및/또는 반환 유형이있는 함수이지만 오버로드 된 생성자와 같이 이름이 다른 시그니처 만 포함하는 함수를 등록하는 방법 여기에서지도의 키가 고유해야하며 따라서 반복 할 수 없다는 점을 고려하면? 필요한 경우 전체 객체 팩토리 코드를 게시 할 수 있습니다. 고맙습니다!

+0

조금 지나치게 설계되지 않았습니까? 공장이 없어도 객체를 직접 생성 할 수 있다는 장점이 있습니까? 당신의 예제에서, 공장이 간단한'auto world = new MatrixTransform (glm :: mat4()) '을 어떻게 치는지 보지 못합니다. 나는 단지'Node *'대신'std :: unique_ptr '를 사용하는 것을 고려할 것이다. –

+0

@Christian Hackl 런타임에 생성해야하는 특정 인스턴스와 동일한 기본 클래스를 공유하는 수많은 클래스가 있으므로 오브젝트 팩토리 패턴을 조사하기 시작했습니다. 그리고 확실히'Node *'대신에'std :: unique_ptr '를 사용할 것입니다. – LastBlow

답변

1

2 가지 가능한 해결책을 생각해보십시오.

매개 변수가없는 함수의 경우 하나, 매개 변수가 하나있는 함수의 경우 두 번째, 매개 변수가 두 개인 함수의 경우 세 번째 맵을 만들 수 있습니다. 이렇게하면 3 개의지도가 생기고 각지도에는 동일한 서명이있는 고유 한지도 항목이 있습니다!

더 간단한 해결 방법은 초기 맵을 유지하고 일반 생성자로 개체를 생성 한 다음 설정 도구를 사용하여 이름 및 행렬 변환 매개 변수를 설정하는 것입니다.

이봐, 그들은 정말로 당신이 대답을 찾기 위해 질문을해야한다고 말한다! 코드에서 꿈꾸십시오.

#include<utility> 
#include<string> 

enum class Type { MatrixTransform, Cube, Sphere }; 

template<Type> 
struct tag {}; 

struct Factory { 
    template<Type T, typename... A> 
    static auto create(A&&... args) { 
     return create(tag<T>{}, std::forward<A>(args)...); 
    } 

private: 
    static auto create(tag<Type::MatrixTransform>) {} 
    static auto create(tag<Type::MatrixTransform>, std::string) {} 
    static auto create(tag<Type::Cube>) {} 
    static auto create(tag<Type::Sphere>) {} 
}; 

int main() { 
    Factory::create<Type::MatrixTransform>(); 
    Factory::create<Type::MatrixTransform>("foo"); 
} 

오버로딩, 템플릿 및 태그 파견 여기에 작업을 수행합니다

+0

충분히 잘 작동하는 지루한 하이테크 솔루션 추천을 위해 Upvoted : –

+0

@Christian Hackl 하, 하, 하, 고마워, 너는 나를 미소 지었다. 이봐 요, 하이테크 솔루션으로 흥분을 던지려는 사람들, 가변 인수를 가진 템플릿 함수를 말하겠습니까? ;-))) – LastBlow

1

당신은 당신이 열거 클래스를 사용하는 수락하면, 그것을 위해지도를 사용할 필요가 없습니다.


주 : 예는 C++ 14이 필요하지만 대신 auto의 오른쪽 반환 형식을 사용의 문제와는 C++ 11도 작동합니다.

+0

먼저지도를 사용해보고 싶었습니다. 당신이 사용하고있는 가변 인자 템플릿을 흥미롭게 찾으십시오. 확실히 시도해 볼 것입니다. 당신의 도움을 주셔서 대단히 감사합니다. – LastBlow

+0

@LastBlow지도에는 고정 유형이 있습니다. 다른 함수 정의를 값으로 사용하려고합니다. 펑터를 사용하지 않는 이상 가능하지 않습니다. 이 경우 단순히 오버로드를 기반으로 솔루션 맨 위에 쓸모없는 레이어를 추가하는 것입니다. – skypjack