2011-07-07 36 views
0

我一直在尋找工廠方法並努力尋找解決方案來解決我的問題(儘管我感覺它是直接向前的。我試圖創建來自相同派生類的對象,這是事先知道,但他們有不同的參數。具有不同參數的對象工廠

class Base 
{ 
public: 
    Base(){}; 
    ~Base(){}; 

    std::string name; 
    double base_input; 
    double output; 

    virtual void relation_function()=0; 
}; 

class Derived1 : public Base 
{ 
public: 
    double private_input; 
    int multiplier; 

    Derived1(std::string , double , double , int); 
    ~Derived1(){}; 

    virtual void relation_function(); 
}; 

class Derived2 : public Base 
{ 
public: 
    double private_input; 
    int multiplier; 

    Derived2(std::string , double , int); 
    ~Derived2(){}; 

    virtual void relation_function(); 
}; 

的參數在派生類中注入根據它們的構造函數。

Derived1::Derived1(std::string input_name, double input_base_input,double input_private_input, 
int input_multiplier){ 
    name=input_name; 
    base_input=input_base_input; 
    private_input=input_private_input; 
    multiplier=input_multiplier; 
}; 



Derived2::Derived2(std::string input_name,double input_private_input,int input_multiplier) 
    { 
     name=input_name; 
     private_input=input_private_input; 
     multiplier=input_multiplier; 
    void relation_function();}; 
    void Derived2:: relation_function(){output=multiplier*private_input;}; 


void Derived1:: relation_function(){output=multiplier*base_input*private_input;}; 

目前,我手動創建派生類的實例如下

std::vector<std::string> v(3); 
v[0]="a";v[1]="b";v[2]="c"; 
for (int n=0;n<=2;n++) 
Base* pderived1(new Derived1(v[n],2,2,1)); 

std::vector<std::string> v(2); 
v[0]="d";v[1]="e"; 
for (int n=0;n<=1;n++) 
Base* pderived1(new Derived1(v[n],5,9,9)); 

這是不理想的,我需要先創建一個指針到派生類的一些實例的前「修理」 /「凍結」一些在構造函數的paramters的來自被創建的構造每個派生類。

base* (*pconstructor){string, double, double, int) = Derived (string, 2,2,1) 

目的是使用該指針構造爲主要工具傳遞到以下功能創建對象前dicate的PARAMATERS。下面的函數將作爲一個工廠來創建衍生物1或衍生物所需的實例/對象的數量,這些實例/對象可能在其構造函數中具有不同的參數,例如derived2。

base* function(std::vector<string>){ create instances.. } 

我不知道如何創建的指針來操作構造函數的參數也將被用來創建實例。任何線索的功能,請.. 感謝大家提前從您的幫助C++新手!

+1

問題是什麼? – iammilind

+0

我不知道如何創建指針來操作構造函數的參數,也沒有將用於創建實例的函數.. –

+0

字廠在這裏爲我提出了一個大紅旗。除非你提供了它的功能描述,否則這將會令人困惑 – Ulterior

回答

0

從這個問題來看,目前還不清楚什麼是實際目標。但是,我不知道你是否可以有一個構造函數/析構函數的成員函數指針。所以你必須放棄這個選擇。

最好在構造函數實例本身做任何檢查。另外下面是一個糟糕的壞主意,因爲它泄漏內存:

for (int n=0;n<=1;n++) 
    Base* pderived1(new Derived1(v[n],5,9,9)); 

您將要覆蓋不止一次pderived1更多。謹慎使用new/malloc

+0

有沒有更好的方法來引用相同派生類(Derived1)的對象,但有不同的參數,但可以用來從Derived2生成對象。每個派生類中的實例可能有不同的參數!非常感謝... –

0

很好地解決了這個問題只是提供的功能有不同的參數:

#include <string> 
#include <typeinfo> 
#include <vector> 
class FactoryFunction; 

class Factory { 
public: 
    template<class T, class P1, class P2> 
    void reg2(T (*fptr)(P1, P2)); 
    template<class T, class P1, class P2, class P3> 
    void reg3(T (*fptr)(P1,P2,P3)); 
    template<class T, class P1, class P2, class P3, class P4> 
    void reg4(T (*fptr)(P1,P2,P3,P4)); 
private: 
    std::vector<FactoryFunction*> vec; 
}; 
Base *derived1_factory(std::string s, double d1, double d2, int i) 
{ 
    return new Derived1(s,d1,d2,i); 
} 
int main() { 
    Factory f; 
    f.reg4(&derived1_factory); 
} 

編輯:這種設計還需要一些東西,可能很難搞清楚,特別是以下類別:

class FactoryFunction { 
public: 
    virtual int NumParams() const=0; 
    virtual void set_parameter(int i, void *p)=0; 
    virtual std::string parameter_type(int i) const=0; 
    virtual void *return_value() const=0; 
    virtual std::string return_type() const=0; 
}; 
template<class T, class P1> 
class FactoryFunction1 : public FactoryFunction 
{ 
public: 
    FactoryFunction1(T (*fptr)(P1)) : fptr(fptr) { } 
    int NumParams() const { return 1; } 
    void set_parameter(int i, void *p) { switch(i) { case 0: param1 =*(P1*)p; break; }; } 
    std::string parameter_type(int i) const { switch(i) { case 0: return typeid(P1).name(); }; } 
    void *return_value(int i) const { return_val = fptr(param1); return (void*)&return_val; } 
    std::string return_type() const { return typeid(T).name(); } 
private: 
    T (*fptr)(P1); 
    T return_val; 
    P1 param1; 
}; 

然後像reg1這樣的函數可以實現將new FactoryFunction1<T,P1>(fptr)存儲到std::vector<FactoryFunction*>。 顯然,reg1/reg2/reg3函數也可以使用std :: string作爲參數。

編輯:哦,reg4只是缺少實現(你也需要實現其他函數)。

 template<class T, class P1, class P2, class P3, class P4> 
     void Factory::reg4(T (*fptr)(P1,P2,P3,P4)) 
      { 
      vec.push_back(new FactoryFunction4(fptr)); 
      } 

讓希望現在編譯:)

+0

非常感謝...這可能需要我幾個月的時間才能掌握,因爲我對簡單的工廠概念很感興趣!看起來我比我的體重高出很多...謝謝。順便說一句,我在你的答案的第一部分得到一個鏈接器錯誤。工廠不能註冊reg4。 reg4應該接受一個指向帶有四個參數的函數的指針,而在f.reg4(&derived1_factory)中,您正在給它提供一個指向Bass的指針的地址而不是指針本身..我錯過了什麼! –

+0

抱歉,它沒有編譯。 (我的代碼稍微大一點,直接工作...)我會嘗試一個測試用例,然後編輯答案。 – tp1