Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Factory Pattern with Heterogenous Constructor Constraint

I'm implementing a C++ program that can programmatically instantiate objects given an input file which provides the class names and arguments to pass to the constructors.

The classes are derived from a common base class but their constructor signature varies.

They are declared as follows:

class Base { ... }
class Class1 : Base { Class1(int a1, int a2); }
class Class2 : Base { Class2(int a1, int a2, int a3); }
... and so on...

The argument types do not have to be int's, in fact they could be any built-in type or complex, custom type.

The program input could look like this in JSON form:

[
  { "Class1": ["arg11", "arg12"] },
  { "Class2": ["arg21", "arg22", "arg23"] },
  ...and so on...
]

Reading through the docs for Boost.Functional/Factory it appears that it could solve my problem were it not for the fact that in my application the constructor signature varies (the heterogeneity constraint). Boost.Function/Factory's approach is to normalize the constructor signatures however this is not possible in my application.

In a dynamic language like Python, this would be rather trivial: obj = klass(*args) where klass = Class1 and args = ["arg11, "arg12"].

So how would one go about implementing the factory pattern with the heterogenous constraint in C++?

Are there other libraries besides Boost that I have overlooked that may be of assistance?

Is it possible to implement this such that the only dependency is the standard library (i.e. no Boost)?

Furthermore, in the case where a constructor argument is of a complex type so that it must be specially constructed from its JSON representation, how does it affect the complexity of the problem?

like image 811
Salman Haq Avatar asked Dec 19 '11 00:12

Salman Haq


1 Answers

Have you considered having a factory method for each class that knows how to construct the object from an "array" of parameters read from the file.

That is:

// declared "static" in header file
Class1* Class1::FactoryCreate(int argc, const char** argv)
{
    if (argc != 2)
        return NULL; // error

    int a1 = atoi(argv[0]);
    int a2 = atoi(argv[1]);
    return new Class1(a1, a2, a3);
}

// declared "static" in header file
Class2* Class2::FactoryCreate(int argc, const char** argv)
{
    if (argc != 3)
        return NULL; // error
    int a1 = atoi(argv[0]);
    int a2 = atoi(argv[1]);
    int a3 = atoi(argv[2]);
    return new Class2(a1, a2, a3);
}
like image 77
selbie Avatar answered Oct 01 '22 13:10

selbie