2011-10-07 38 views
0

Is there a way to instantiate objects from a string holding their class name?如何從包含類名的字符串實例化其構造函數需要參數的對象?

我得到了一個問題基本上與上述問題相同。但我需要用一些參數實例化一個類。不同的類構造函數名稱可能需要不同數量的變量,每個變量的類型也可能不同。而且因爲這個類包含了常量變量,所以你不能用新的T()將它新增,然後將該參數設置爲正確的值。 「類名」 - 「構造函數」地圖似乎不適合我的需要。

任何替代品?

+0

您基本上必須在鏈接問題中擴展該方法,以根據字符串中的參數數量委託給多個創建函數。如果類構造函數可以解析字符串本身,只需將其從默認構造更改爲單個字符串參數構造函數即可。 –

回答

1

我要說的是,也許C++不是你想要完成的任何事情的正確語言。你越想通過外部數據來控制你的程序,你就越接近編寫腳本的程度。當這是你的目標時,有很多更強大的選擇。

這就是說,當然有可能,雖然不是那麼容易。想到兩種方法。首先是要求所有適用的類型都有一個接受std::string的構造函數。這個構造函數將負責它自己的解析。

template<typename T> Base * createInstance(const std::string& s) { return new T(s); } 
typedef std::map<std::string, Base*(*)(const std::string&)> map_type; 
//...and similar changes as needed 

如果你不想改變你的類型定義,或者這是不可接受[也許你的類型已經有了這樣一個構造函數?],擺脫模板createInstance方法,併爲每個單獨的版本你感興趣的類型。這個函數執行解析,並調用相應的構造函數。

map["derivedA"] = createDerivedA; 
map["derivedB"] = createDerivedB; 

第三種選擇威力使用可變參數模板可以[或升壓式的可變參數類模板],將帶你回到原來的簡單。

template<typename T, typename... Args> 
Base* create(std::string) { 
    //somehow pass the string to a generic function that packs the arguments into a tuple 
    //then somehow unpack that tuple and pass the bits to the constructor 
} 

map["derivedA"] = create<derivedA, int, double, std::string>; 

但是,我不知道如何解決這個問題,或者即使這是可能的。

0

您可以使用工廠設計模式。將你的字符串傳遞給工廠類,然後讓它解碼你的字符串,選擇正確版本的構造函數和類來調用。它會傳回正確類的實例以供其餘代碼使用。 這裏是一些信息factory design pattern

相關問題