Object Factory with different parameters
I've been looking at factory method and struggled to find a solution to my problem (although i have the feeling it is straight forward.I'm trying to create objects that come from the same derived class, which is know in advance but they have different parameters.
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();
};
the parameters are injected in the derived class based on their constructors.
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;};
Currently i'm creating instance of the derived class manually as follows
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));
which is not idea开发者_开发百科l, i need to create first a pointer to the constructor of the derived class to "fix"/"freeze" some of the paramters in the constructor functions before a number of instances are created from each derived class.
base* (*pconstructor){string, double, double, int) = Derived (string, 2,2,1)
the aim is to use this pointer to the constructor as the main tool to dicate the paramaters before passing to the following functions to create the object. the function below would act as a factory to create the number of instances/objects required from derived1 or derived which may have different parameters in their constructor functions like derived2.
base* function(std::vector<string>){ create instances.. }
i dont know how to create the pointer to manipulate the constructor parameters nor the function that would be used to create the instances.. Any clues, please.. Thanks you all in advance for your help from a c++ novice!
From the question, it's unclear that what's the actual goal. However, I am not aware if you can have a pointer to member function for constructor / destructor. So you have to give up for that option.
It's better to do whatever check while constructor instance itself. Also following is a bad bad idea, as it leaks memory:
for (int n=0;n<=1;n++)
Base* pderived1(new Derived1(v[n],5,9,9));
You are overwriting pderived1
more than once. Cautious with use of new
/malloc
.
good solution to this problem is just providing functions with different parameters:
#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);
}
Edit: This design also requires some stuff that might be difficult to figure out, in particular the following classes:
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;
};
Then a function like reg1 could be implemented to store new FactoryFunction1<T,P1>(fptr)
to a std::vector<FactoryFunction*>
.
Obviously reg1/reg2/reg3 functions can have std::string as a parameter too.
Edit: oh, reg4 is just missing implementation (you need to implement other functinons too).
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));
}
Lets hope it compiles now :)
精彩评论