2010-08-21 38 views
1

我需要編寫一個可以創建任何類型對象的函數。它接收類名作爲參數。 如果類相似,我們可以從單個基類中派生所有這些類,並讓函數返回Base *。函數的用戶可以使用運行時多態來使用返回的對象。在這種情況下,函數如下所示。如何編寫單個函數以基於classname參數爲不相似的類創建不相似的對象?

Base* createObject(string objName) 
{ 
    if(objName == "D1") 
     return new D1; 
    else if(objName == "D2") 
     return new D2; 
    return NULL; 
} 

如果類不相同,它們不能從單個基類繼承,因爲它不適當的繼承。在這種情況下,上面的函數將不會有用。假設我有3個不同的類,如直升機,廚房和學院。 在這種情況下,單個函數如何創建任何類型的對象? 我有一個像下面的解決方案。 使用包裝類來包裝Union中的所有不相似的類指針。 然後讓函數創建Wrapper對象並根據傳遞給它的類名填充適當的類指針。 這個載體作用類似於下

Wrapper* createObject(string objType) 
{ 
    Wrapper *pWrapper = new Wrapper(); 
    pWrapper->objectType = objType; 
    if(objType == "Helicopter") 
    { 
     pWrapper->pHelicopter = new Helicopter; 
    } 
    else if(objType == "Kitchen") 
    { 
     pWrapper->pKitchen = new Kitchen; 
    } 
    else if(objType == "College") 
    { 
     pWrapper->pCollege = new College(); 
    } 
    return pWrapper; 
} 

包裝類看起來像下面。

class Wrapper 
{ 
    public: 
    string objectType; 
    union 
    { 
     Helicopter *pHelicopter; 
     Kitchen *pKitchen; 
     College *pCollege; 
    }; 
}; 

有沒有比上面更好的解決方案?

+1

如果類型無關,該類的用戶如何使用運行時多態來使用它們?你能提供更大的圖片,你想解決什麼問題?我覺得你寫的一個功能很難用,因爲它是用來寫的。 – 2010-08-21 09:20:20

+0

@Charles:我寫道,如果類型相似,那麼函數的用戶可以使用運行時多態性。當函數返回Base *時,他可以調用派生類的任何虛函數。如果類型不相似,則無法使用運行時多態性。 – bjskishore123 2010-08-21 09:46:20

+0

問題在於,在不知道自己想要達到什麼的情況下,不可能真正給出明智的建議。這個問題不應該發生在適當的設計中。 – 2010-08-21 10:03:12

回答

0

加速已經有您的問題2個可能的解決方案:Boost.VariantBoost.Any

但最好你應該避免這樣的設計,如果可以的話。如果一個函數返回不相關的對象,並且你不能重構給這些類型一個通用的接口,你應該把它分成多個函數。

1

包裝的想法在我眼中是一個不走。它讓用戶不適當地使用多態性令人困惑。我會爲每個邏輯組或者所有具有相同基類的類使用create函數。這可能會導致一些創建功能,但在這種情況下,您應該過度考慮您的設計。另一個解決方法是定義一個抽象接口類「可創建」左右,但我不喜歡它。 ;-)

0

如果你願意使用'枚舉'而不是'字符串',這是一個可能的解決方案。它不會避免單一功能,但至少擺脫了那巨大的if-else

enum X {HELI, SHIP, BUS, TRAIN, COLLEGE, KITCHEN}; 

struct Heli{ 
}; 

struct College{ 
}; 
.... 
template<X x> struct Creator{ 
}; 

template<> struct Creator<HELI>{ 
    Heli *Create(){return new Heli();} 
}; 

template<> struct Creator<COLLEGE>{ 
    College *Create(){return new College();} 
}; 

int main(){ 
    Heli *ph = Creator<HELI>().Create(); 
    College *pc = Creator<COLLEGE>().Create(); 
    delete ph; 
    delete pc; 
} 
相關問題