2012-06-19 46 views
2

我不擅長OOP設計,但我需要向潛在的僱主展示我的知識。 情況如下:使用C++填充地圖容器時的多形態設計

我有一個帶有鍵值類型參數的文件,名爲parameters.txt。 我有一個map <string, CommonParamValue>作爲容器。我需要用元素填充它,使用帶參數的文件。密鑰始終爲std::string參數,CommonParamValue可用int,double,string和標準函數調用表示。爲了實現這個,CommonParamValue是一個帶有虛擬方法的基類。它有孩子 - StringParamValue,DoubleParamValue,CurTimeParamValue。基類和每個孩子都有一個方法virtual string GetValue(),它返回內部數據的字符串表示形式; virtual void SetValue(string)設置值。

問題是如何使用多態性在運行時使用適當的數據填充容器map <string, CommonParamValue>現在我有這樣的情況:

parameters.txt

*user_name=Jane 
*order_number=1325 
current_date= 

常規填充地圖

ifstream in(fileParamsPath); 
    if (! in) 
    { 
     cout << "Cannot open file with parameters, program is terminating." << endl; 
     cin.get(); 
     exit(-1); 
    } 
    string key = "", value = ""; 
    while(in) 
    { 
     getline(in, key, '='); 
     getline(in, value, '\n'); 

     // put key and value into the container 
     // right here we need to analyze the data type and choose appropriate container. 
     // CommonParamValue *paramValue = new DoubleParamValue(); or 
     // CommonParamValue *paramValue = new CurTimeParamValue(); or 
     // CommonParamValue *paramValue = new StringParamValue(); 

     paramValue->SetValue(value); 
     params.insert(make_pair(key, *paramValue)); // params is a map <string, CommonParamValue> 
     delete paramValue; 
    } 
    in.close(); 

有一個主意,讓值參數的類型文件parameters.txt並在填寫時進行分析map <string, CommonParamValue>

parameters.txt

*user_name=Jane 
string 

*order_number=1325 
int 

current_date= 
function 

並修改常規填充map <string, CommonParamValue>這樣:

string key = "", value = "", type = ""; 
    while(in) 
    { 
     getline(in, key, '='); 
     getline(in, value, '\n'); 
     getline(in, type, '\n'); 
     in.get(); // got the dividing empty string 
     // put key and value into the container 
     // right here we need to analyze the data type and choose appropriate container. 
     if(type == "int") 
     { 
      CommonParamValue *paramValue = new IntParamValue(); 
     } 
     else if(type == "function") 
     { 
      CommonParamValue *paramValue = new CurTimeParamValue(); 
     } 
     else if(type == "string") 
     { 
      CommonParamValue *paramValue = new StringParamValue(); 
     } 
     else 
     { 
      // error 
      exit(1); 
     } 

     paramValue->SetValue(value); 
     params.insert(make_pair(key, *paramValue)); // params is a map <string, CommonParamValue> 
     delete paramValue; 
    } 

那是一個很好的決定還是壞?也許我的潛在僱主希望我以其他方式實施,但我只有這個決定。對於初級C++程序員有沒有更好的方法?

+0

您不能存儲在包含基類對象映射子類的對象。 http://en.wikipedia.org/wiki/Object_slicing你需要'boost :: ptr_map'或類似的東西。 –

回答

2

適用的最經典的設計是factory method design

CommonParamValue* createParamValue(const std::string &value); 

createParamValue方法以創建派生ParamValue適當的,並返回它作爲一個CommonParamValue的責任。

通過使用值字符串推斷createParamValue中的類型,可以避免將「類型」的附加字符串抽成parameters.txt。 A regular expression聽起來像intdoubleCurTime最優雅。 Boost regex是一個示例庫,可讓您在C++中執行此操作。但是,當然如果你正在尋找一個快速解決方案,那麼編寫你自己的30行決策樹不應該是這些簡單語法的問題。

1

客戶端代碼中的if語句對我來說有點不適應。可以嘗試一個工廠類?

有一個基類IParamValue

IntParamValue : public IParamValue { } 

static IParamValue * Create(string selection); 

IParamValue * IParamValue::Create(string selection) 
{ 
    if (selection == "int") return new IntParamValue(); 
    ... 
} 

客戶端代碼:

IParamValue* param = IParamValue::Create ("something"); 
+0

非常感謝,我會閱讀關於工廠設計模式。 –