2010-11-21 3 views
2

저는 Java 방식으로 프로그래밍을 너무 오래하고 C++로 돌아가는 길을 찾아 왔습니다. 클래스 (type_info 또는 문자열의 이름)가 해당 클래스의 인스턴스를 만들 수있는 코드를 작성하려고합니다. 간단히하기 위해 기본 생성자 만 호출하면된다고 가정 해 봅시다. 이것은 C++에서도 가능합니까? 그렇다면 앞으로 TR에 올 것입니까?C++에서 객체의 유형을 인스턴스화 할 수 있습니까?

나는 이것을 할 수있는 방법을 찾았지만 좀 더 "동적 인"것이 있기를 바라고 있습니다. 인스턴스화하고자하는 클래스 (이 문제는 자체적으로 문제이므로 구성에 대한 결정을 남기고 싶음)를 위해 다른 클래스에 자체 등록하는 정적으로 작성된 인스턴스가있는 싱글 톤 팩토리를 만들었습니다. 예. 클래스 Foo에는 정적 FooFactory 인스턴스가있는 FooFactory도 있습니다. 따라서 프로그램 시작시 FooFactory 생성자가 호출되어 다른 클래스에 자신을 등록합니다. 그런 다음 런타임에 Foo를 만들려면 FooFactory를 찾고 Foo 인스턴스를 생성하기 위해 호출합니다. C++에서이 작업을 수행하는 데 더 좋은 것이 있습니까? 나는 Java/C#에서 풍부한 리플렉션으로 버릇이 없다고 생각합니다.

맥락에서 필자는 Java 세계에서 익숙해 진 IOC 컨테이너 개념을 C++에 적용하려고 노력 중이며 Factory를 추가 할 필요없이 가능한 한 동적으로 만들 수 있기를 바라고 있습니다. 내 모든 다른 클래스에 대한 클래스.

+0

후속 조치로 C++에서 "유형"을 전달할 수 있습니까? 즉. Foo 객체가 아니라 Foo 클래스를 함수의 매개 변수로 전달할 수 있습니까? 내가 생각하고있는 Java 동급 클래스는 Class 매개 변수를 사용하는 메서드이며 Foo.class를 전달할 수 있습니다. – Greencpp

답변

0

나는이 당신을 위해 무엇을 찾고 있는지 모르겠지만 당신은 항상, 템플릿을 사용할 수 있습니다

template <typename T> 
T 
instantiate() 
{ 
    return T(); 
} 

아니면 클래스는 :

template <typename T> 
class MyClass 
{ 
    ... 
}; 
+0

Thanks Joe. 예, 템플릿을 사용하면 팩토리를 구현하는 데 필요한 코드 줄을 다듬을 수 있습니다.하지만 동적으로 생성되는 클래스 당 팩토리를 작성하지 않는 방법을 찾고 싶습니다. 나는 내가하지 않을 것이라고 생각한다. – Greencpp

-1

은 제 방법이 없습니다 형식의 이름에서 실제 형식으로 이동합니다. 풍부한 리플렉션은 꽤 멋지지만 거의 항상 좋은 방법이 있습니다.

+1

예, C++에서 IOC을 수행하는 Java 방식에 맞게 도매하려고 시도하는 것이 저의 첫 실수라고 생각합니다. 여전히 Spring에서 config 클래스를 동적으로 연결하는 것은 매우 강력합니다. 내 공장 접근 방식은이 욕구를 충족 시키며, 내가 원하는만큼 깨끗하지는 않습니다. – Greencpp

+1

BTW, 여기에 -1을주었습니다. 왜 ... 요나단과 왜 동의하지 않는지에 관심이 있습니다. – Greencpp

+0

권자 :) 각자 자신에게. –

-1

"var"또는 "dynamic"과 같은 것은 C++에서 마지막으로 내가 확인한 바는 없다 (비록 이전에 있었지만). (void *) 포인터를 사용하고 그에 따라 캐스팅을 시도 할 수 있습니다. 또한 메모리가 제대로 작동한다면 C++은 리플렉션이 아닌 RTTI를 가지지 만 런타임에 유형을 식별하는 데 도움을 줄 수 있습니다. C++에서

+1

C++ 0x의'auto'는 C#의'var'과 거의 같습니다. 둘 다 역동적 인 타이핑과는 아무런 관련이 없습니다. – fredoverflow

0

에 오신 것을 환영합니다 :)

당신은 당신이 그 객체를 생성하기 위해 Factory을해야한다는 올바른지, 그러나 당신은 파일 당 하나의 Factory이 필요하지 않을 수 있습니다.

은 모든 instanciable 클래스를 데에가는 일반적인 방법은 당신이 당신에게 할 때마다 std::unique_ptr<Base> 서비스를 제공하는 하나의 Factory이 필요합니다 수 있도록 우리가 Base를 호출한다는 공통 기본 클래스에서 파생.

구현하는 두 가지 방법이있는 Factory : 당신은 Prototype 패턴을 사용하고 clone 함수가 호출 될에 만들 수있는 클래스의 인스턴스를 등록 할 수 있습니다

  • .
  • 당신은 함수에 대한 포인터 또는 (C++ 0X 또는 std::function<Base*()>) 펑터 물론

어려움이 동적으로 이러한 항목을 등록하는 것입니다 등록 할 수 있습니다. 이는 일반적으로 정적 초기화 중에 시작될 때 수행됩니다.

// OO-way 
class Derived: public Base 
{ 
public: 
    virtual Derived* clone() const { return new Derived(*this); } 
private: 
}; 

// start-up... 
namespace { Base* derived = GetFactory().register("Derived", new Derived); } 

// ...or in main 
int main(int argc, char* argv[]) 
{ 
    GetFactory().register("Derived", new Derived(argv[1])); 
} 

// Pointer to function 
class Derived: public Base {}; 

// C++03 
namespace { 
    Base* makeDerived() { return new Derived; } 
    Base* derived = GetFactory().register("Derived", makeDerived); 
} 

// C++0x 
namespace { 
    Base* derived = GetFactory().register("Derived", []() { return new Derived; }); 
} 

시동 방식의 가장 큰 장점은 완벽하게 거기에 등록을 자체 파일에 Derived 클래스를 정의 감싸 할 수 있으며, 다른 파일이 변경에 의해 영향을하지 않습니다. 이것은 의존성을 다루기에 좋습니다.

반면에 생성하려는 프로토 타입에 외부 정보/매개 변수가 필요한 경우 초기화 메소드를 사용해야합니다. 가장 간단한 방법은 인스턴스를 main (또는 이와 동등한 것)에 등록하는 것입니다. 필요한 매개 변수가 있습니다.

빠른 참고 : 후속 질문에 대해서 ...

기능 방법에 대한 포인터가 가장 경제적 (메모리)와 (실행)에서 가장 빠른이지만, 구문이 이상해.

네, 아마도 직접적으로하지만, 함수에 유형을 통과 할 수 있습니다 : 문제의 유형이 컴파일 타임에 알려진 경우 당신은 몇 가지가 필요합니다하지만

  • , 당신은 템플릿을 사용할 수 있습니다 시간은 구문을 알고 당신이 object.class에 가까운 무언가를 전달해야하는 경우에, 당신은 공장 출하 방법을

를 ID의 어떤 종류를 전달하고 사용해야합니다하지 않을 경우는

  • 그것은 나에게 보인다하세요 당신은 이중 파견 유스 케이스에 접근하고 있습니다. 그리고 Visitor 패턴을 살펴볼 가치가 있습니다.

  • 관련 문제