2011-12-19 83 views
6

我正在实现一个C++程序,该程序可以编程实例化给定输入文件的对象,该输入文件提供要传递给构造函数的类名称和参数。具有异构构造函数约束的C++工厂模式

这些类是从一个公共基类派生的,但它们的构造函数签名有所不同。

它们的声明如下:

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

的参数类型没有为int的,事实上,他们可以是任何内置类型或复杂的自定义类型。

程序输入可能看起来像这样以JSON形式:

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

阅读过的文档进行Boost.Functional/Factory看来,它可以解决我的问题,如果不是事实,我的应用程序构造函数签名的变化(异质性约束)。 Boost.Function/Factory的方法是规范化构造函数签名,但这在我的应用程序中是不可行的。

在像Python这样的动态语言中,这将是相当平凡的:obj = klass(*args)其中klass = Class1args = ["arg11, "arg12"]

那么如何实现工厂模式与C++中的异构约束呢?

除了Boost以外,还有其他的库,我忽略了这可能是有帮助的吗?

是否有可能实现这样的唯一依赖项是标准库(即不提升)?

此外,在构造函数参数是复杂类型的情况下,它必须从其JSON表示特别构造,它是如何影响问题的复杂性的?

+0

供将来参考,均匀的相对是异质 –

+2

嘿塞特, “不均匀”也根据韦氏字典一个有效字,并且在意义“不同”的相似。 我选择了前者,因为这也是Boost.Function/Factory文档的选择(请参阅我的文章中的链接)。 –

+0

是的,我知道,你可以添加“in”或“un”几乎任何单词,它仍然是一个单词。这听起来很奇怪。 –

回答

1

要达到你想要什么,你需要在代码中的某个点上,一个巨大的switch语句来决定构建基于名称(实际上,一个switch哪一类将无法工作,因为您无法打开字符串 - 更像是很长的if - else if)。

此外,您显示的表示看起来似乎不包含有关构造函数参数类型的任何信息。如果你有一个具有多个构造函数的类可以调用相同数量的参数,那么这可能是一个问题。

最后,我认为最好的做法是用@selbies answer之类的东西,但使用代码生成为您生成构建代码。

+0

谢谢@bjorn&selbie。 对于我的用例,最好的答案是代码生成。 我的代码生成器是〜100行Python,并生成_approximately_有效的工厂函数。即我必须按摩一些生成的代码。即使使用不完美的代码生成器,我在完成此任务方面也非常有成效。 它可能仍然值得扩展Boost.Functional /工厂为我的用例。稍后再探讨。 :) 仅供参考:C++头文件解析库:[CppHeaderParser库](https://bitbucket.org/senex/cppheaderparser/src),这对我的需求是足够的。 –

5

您是否考虑过为每个知道如何从文件中读取参数的“数组”中构造对象的类的工厂方法。

即:

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

我当然已经考虑过一个类似于此的选项......即将JSON对象传递给静态工厂函数并让它返回实例。问题是我正在处理的代码库有100多个这样的类,并且这个类正在增长。所以虽然这肯定是一个可能的解决方案,但我现在毫不犹豫地称它为理想。 –

相关问题