2013-10-23 4 views
1

텍스트 파일에서 형식을 읽고 인스턴스를 만들려고합니다. 예 :문자열에 저장된 형식으로 인스턴스를 만드는 방법

class MyType { 
    public: 
      MyType() {} 
      ~MyType() {}  
}; 

char* type = "MyType"; 
type object = type(); 

나는 이것이 정확하지 않다는 것을 알고 있지만, 나는 그것이 무엇을 잘하려고 하는지를 설명한다고 생각한다. 어떻게 할 수있는 방법이 있는지 묻는 중입니다. typeid(Type).name();을 통해 유형을 문자열로 변환하는 방법이 있다는 것을 알고 있지만이를 역전시킬 방법이 있습니까? 문자열을 유형으로 변환하는 것을 의미합니다.

읽기에 감사드립니다. :)

편집 : 아직 얻을 수없는 경우 . 내가 원하는하는 것은 당신은 소스 코드를 원하는 사람 아래 사람에 대해서는 상기 design pattern factory

를 사용해야이

var myObj = Activator.CreateInstance(Type.GetType(namespaceName + className)); 
+0

당신은 클래스 팩토리 패턴을 사용한다. – Andrey

+0

파일이나 전체 정의에서 인스턴스화 할 * * 유형을 읽고 싶습니까? – Sarien

+0

another : http://stackoverflow.com/questions/19036462/c-generic-object-factory-by-string-name – Basilevs

답변

3

같은 C#에서 수행 할 수 있습니다, 신속하고 더러운 공장이있다. 그것은 ++ 11 c를 사용 , 그것은 한 그들은 모두

#include <iostream> 
#include <functional> 
#include <memory> 
#include <map> 

template<class key,class Base,class ...Args> class Factory 
{ 
    using creator = std::function<std::unique_ptr<Base>(Args...)>; 
    std::map<key,creator> m; 
public: 
    void registerF(key s,creator c) 
    { 
     m[s]=c; 
    } 

    std::unique_ptr<Base> operator()(key s,Args... a) 
    { 
     return m[s](a...); 
    } 
}; 

struct A{virtual void foo()=0;}; 
struct B1 : A{virtual void foo(){std::cout<<"B1"<<std::endl;}}; 
struct B2 : A{virtual void foo(){std::cout<<"B1"<<std::endl;}}; 

template <class T> std::unique_ptr<T> creater() 
{ 
    return std::unique_ptr<T>(new T()); 
} 

int main() { 
    Factory<std::string,A> f; 
    f.registerF("B1",&creater<B1>); 
    f.registerF("B2",&creater<B2>); 
    auto p=f("B1"); 
    p->foo(); 

    return 0; 
} 

편집 생성 기능을 통해 동일로, const를-정확하지 않은 생성자의 인수에 대한 기본적인 지원을하고있다 : 당신은 실체화하려고하면 등록되지 않은 문자열을 가진 클래스는 맵의 연산자 []가 빈 std :: function을 호출하고 호출하기 때문에 bad_function_call 예외가 발생합니다. 예를 들어 공장

+1

이 답변은 사람들이 소스 코드를 따를 필요가 없도록 소스 코드를 제공하면 훨씬 향상 될 것입니다. 링크를 클릭하여 답변을 얻으십시오. –

+0

나는 소스 코드를 제공하는 것이 싫다. 팩토리를 구현하는 방법에는 여러 가지가 있습니다 (복제, 자유 기능 사용). 당신은 무언가를 간단하고 무언가를 할 수 있습니다 variadic emplates 다른 것들과 함께 훨씬 더 복잡한 ... 그에게 자신을 향상시킬 수있는 가장 좋은 방법은 그에게 기술의 이름을 부여하고 그 나머지를하게하는 것입니다 – Davidbrcz

+1

그래서 목표 중 하나 프로그래밍 질문에 대한 정식 답변을 원 스톱 상점으로 만드는 것입니다. 힌트, 전문적 유행어 및 다른 사이트에 대한 링크 만 제공하는 것은 어려운 일입니다. SO는 정보의 기본 소스 *가되도록 의도되었으므로 기본 소스에 대한 링크를 찾을 수있는 곳이 아닙니다. 가장 많은 상향 된 답변을 둘러 보면 소스 코드에 설명 된 높은 수준의 세부 묘사와 복잡한 아이디어가 공통 패턴으로 등장합니다. –

0

:

class MyBase {}; 
class MyTypeA : public MyBase {}; 
class MyTypeB : public MyBase {}; 

std::shared_ptr<MyBase> make_instance(std::string type) 
{ 
    if(type == "MyTypeA") 
     return std::make_shared<MyTypeA>(); 
    else 
     return std::make_shared<MyTypeB>(); 
} 

(당신은 내가 생각하는 일부 <memory> 같이 포함해야합니다)

+0

OP가 찾고있는 것만 큼 "마법 같은"것은 아니지만 그럼에도 불구하고 훌륭한 실행 가능한 솔루션입니다. –

+0

Côme David and wal-o-mat, 답장을 보내 주셔서 감사합니다. 그러나 모든 클래스를 하드 코딩해야하므로 공장에서 필요하지 않습니다. 팩토리 나 make 함수에 추가 코드를 추가하지 않고 기본 클래스를 상속 할 수 있어야합니다. 문자열을 유형을 확인하지 않고 유형을 선택하지 말아야합니다. –

+0

@AmitHendin : 당신이 요구하는 것은 C++에서는 불가능합니다.최소한, 끔찍한 영리한 코드가 없으면 불가능하며, 영리한 코드조차도 이런 식으로 보일 것입니다. 왜 필요하다고 생각하십니까? –

관련 문제