C ++ Factory Pattern with constraints of heterogeneous constructors

I am implementing a C ++ program that can programmatically create objects specified by an input file that provides class names and arguments passed to the constructors.

Classes are derived from a common base class, but their constructor signature changes.

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... 

Argument types should not be int, in fact they can be any built-in type or complex, custom type.

Entering program data may look like this in the form of JSON:

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

Reading through Boost.Functional / Factory docs seems like it could solve my problem if it werenโ€™t for the fact that in my application the constructor signature is changing (heterogeneity restriction). The Boost.Function / Factory approach is the normalization of constructor signatures, however this is not possible in my application.

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

So, how could a factory template with a heterogeneous constraint be implemented in C ++?

Are there other libraries besides Boost that I overlooked that might be useful?

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

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

+6
source share
2 answers

To achieve what you want, at some point in your code, you will need a giant switch -statement to decide which class to build based on the name (in fact, switch will not work because you cannot include strings - more like very long if - else if ).

In addition, it appears that the displayed view does not contain any information about the type of constructor arguments. This can be a problem if you have a class that has multiple constructors called with the same number of arguments.

In the end, I think it's best if you go with something like @selbies answer , but use code generation to generate the construction code for you.

+1
source

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

I.e:

 // 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); } 
+5
source

Source: https://habr.com/ru/post/904042/


All Articles