2012-02-09 3 views
2

Qt는 슬롯에 템플릿을 허용하지 않으므로 다음 솔루션을 성공 시키려고했습니다. 먼저플러그인 메커니즘을 통해 런타임 중에 동적으로 데이터 유형을로드하는 방법

A는이 같은 목록을 만들고 싶습니다 :

list commands = 
0, "MyDashboard", DashBoard0 
1, "MomsDashboard", Dashboard1 

대시 보드 0과 1이 모두 위젯

에서 파생 된 당신은 우리가 목록에 문자열을 추가 QListWidget하고 있다고 가정하자 다음 연결을 수행하십시오 :

connect(listWidget, SIGNAL(itemClicked(QListWidgetItem*)), 
     this, SLOT(addDashboard(QListWidgetItem*))); 

void addDashboard(QListWidgetItem* item) { 
    int index = listWidget->row(item); 

    QWidget* widget = new typeof(command.atIndex(index).getType()); 
    widget->show(); 

} 

C# 유형에서와 같이 해당 목록 및 저장소 유형을 어떻게 작성합니까?

+2

Emile의 답변에서 귀하의 의견을 읽었을 때, 질문을 명시 적으로 편집해야합니다 - 컴파일시 알려진 유형입니까, 아니면 플러그인 메커니즘을 통해 동적으로로드되는 유형입니까? – cmannett85

답변

3

C++에서는 유형을 런타임에만 알 수있는 객체 (new 연산자 사용)를 만들 수 없습니다. 그러나 해결 방법으로 Factory Method 패턴의 단순화 된 양식을 사용할 수 있습니다.

여기 예입니다 : 아주 예쁜

// Type IDs that are associated with a widget type 
enum WidgetTypeId { 
    dashboard1WidgetTypeId, 
    dashboard2WidgetTypeId 
}; 

// Factory method 
QWidget* createWidget(WidgetTypeId type) { 
    switch (type) 
    { 
     case dashboard1WidgetTypeId: 
      return new DashBoard0; 

     case dashboard2WidgetTypeId: 
      return new DashBoard1; 
    } 
} 

void addDashboard(QListWidgetItem* item) { 
    int index = listWidget->row(item); 

    QWidget* widget = createWidget(command.atIndex(index).getWidgetTypeId()); 
    widget->show(); 

} 

아니, 나는 알고있다. 위젯이 복제 가능하면 추한 switch 문 대신 std::map을 사용할 수 있습니다. 이 대체 방법은 Prototype Pattern의 예입니다. 다음은이 접근법을 보여주는 몇 가지 샘플 코드입니다.

class WidgetFactory 
{ 
public: 
    QWidget* create(const std::string& name) { 
     return prototypes_[name]->clone(); 
    } 

    void addPrototype(const std::string& name, QWidget* prototype) { 
     prototypes_[name] = prototype; 
    } 

private: 
    std::map<std::string, QWidget*> prototypes_; 
} 


WidgetFactory factory; 
factory.addPrototype("DashBoard0", new DashBoard0); 
factory.addPrototype("DashBoard1", new DashBoard1); 


void addDashboard(QListWidgetItem* item) { 
    int index = listWidget->row(item); 

    QWidget* widget = factory.create(command.atIndex(index).getWidgetTypeName()); 
    widget->show(); 

} 

C++은 매우 동적 인 언어가 아닙니다. RTTI 기능이 제한되어 있으며 C#의 리플렉션 기능은 거의 없습니다. 그래서 Factory Method 및 Abstract Factory와 같은 패턴에 의존해야합니다.


그것은 Qt는 (나는 단순한 유틸리티 애플 리케이션을위한 Qt를 사용 C++에서 일반적으로 볼 수 있습니다 것 이상의 런타임 클래스 정보를 제공 할 수 있습니다, 그래서하지 않는 것이 떠올랐다하지 않은

모든 종을 알으십시오 & 휘슬은 그 구조에서 유효하다). 이를 염두에두고 Qt 객체를 클래스 이름으로 인스턴스화하는 방법에 대해이 메일 링리스트 discussion을 검색하여 찾았습니다. 비록 그 솔루션이 플러그인 객체에 대해 작동하는지 모르겠다.

+0

하지만 QWidget * test2 = new typeof (EmptyWorkspace)와 어떻게 다릅니 까? 또는 템플릿 QWidget * testing() {return new T(); } 이에? 이 문제를 어떻게 해결할 수 있습니까? 내가하고 싶은 것은 내가 어떤 클래스를 어떤 버튼에 만들지 정의하는 목록을로드하는 것이다. 버튼을 클릭하면 해당 위젯이 생성되어 QStackedWidget에 추가됩니다. 클래스로 패키지를로드하므로 런타임 중에 목록이 작성됩니다. – chikuba

+1

설명을 위해 작은 코드 샘플을 작성하고 있습니다. –

+0

typeof는 실제로 컴파일러 확장 기능인 컴파일 타임 "함수"입니다. 컴파일 타임에 어떤 타입으로 만 평가할 수 있습니다. C#에서 온 것으로 가정하면 런타임 리플렉션을 사용할 수 없으므로 사용되는 많은 것들을 사용할 수 없습니다. 주된 이유 중 하나는 성능 및 공간 문제이며 이러한 시스템을 제자리에 두려면 컴파일러 구현을 제한해야합니다. 이 문제를 해결할 수있는 좋은 방법에 대해 생각해 볼 것이지만, 무차별 방식은 커다란 switch 문과 함께 각 함수의 경우와 함께 특정 함수의 새 인스턴스를 반환하는 함수가 될 것입니다.이것은 추한 것입니다 : P –

관련 문제