Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;具有异构构造函数约束的工厂模式 我正在实现一个C++程序,它可以编程实例化给定输入文件的对象,该文件提供类名和参数传递给构造函数。_C++_Templates_Boost_Dispatcher_Factory Pattern - Fatal编程技术网

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

C++;具有异构构造函数约束的工厂模式 我正在实现一个C++程序,它可以编程实例化给定输入文件的对象,该文件提供类名和参数传递给构造函数。,c++,templates,boost,dispatcher,factory-pattern,C++,Templates,Boost,Dispatcher,Factory Pattern,这些类派生自一个公共基类,但它们的构造函数签名不同 声明如下: 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

这些类派生自一个公共基类,但它们的构造函数签名不同

声明如下:

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...
]
通读文档似乎可以解决我的问题,如果不是因为在我的应用程序中构造函数签名不同(异构约束)。Function/Factory的方法是规范化构造函数签名,但这在我的应用程序中是不可能的

在像Python这样的动态语言中,这是相当简单的:
obj=klass(*args)
where
klass=Class1
args=[“arg11”,arg12]

那么如何在C+++</P >中实现异构约束的工厂模式? 除了Boost之外,还有其他我忽略的图书馆可以提供帮助吗

是否有可能实现这一点,从而使唯一的依赖关系是标准库(即没有Boost)


此外,如果构造函数参数是复杂类型的,因此必须从其JSON表示中专门构造,那么它如何影响问题的复杂性?

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

即:

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

要实现您想要的功能,您需要在代码中的某个点上使用一个巨大的
开关
-语句来决定基于名称构造哪个类(实际上,
开关
不起作用,因为您无法打开字符串-更像是一个非常长的
if
-
else if

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


最后,我认为最好使用类似的方法,但使用代码生成为您生成构造代码。

我知道我有点晚了,但是C++17有一个很好的现代解决方案。主要思想是将类型擦除与std::any一起使用,它允许您存储不同的构造函数特征类型。该库有点特定,但有充分的文档记录和测试

以下是获得所述方法基本概念的最小示例:

模板
阶级工厂
{
使用BasePtrT=std::unique\u ptr;
公众:
模板
无效注册表类型(常量std::string和name)
{
使用CreatorTraitT=std::函数;
CreatorTraitT trait=[](Args…Args){
返回标准::使_唯一(args;
};
_特征。安置(姓名、特征);
}
模板
BasePtrT创建(const std::string&name,Args…Args)
{
使用CreatorTraitT=std::函数;
const auto found_it=_traits.find(name);
如果(找到它==\u traits.end()){
返回空ptr;
}
试一试{
auto creator=std::any\u cast(找到它->秒);
返回创建者(std::forward(args)…);
}
catch(const std::bad_any_cast&){
返回空ptr;
}
私人:
标准::地图特征;
};
结构接口
{
virtual~Interface()=默认值;
};
结构混凝土:界面
{
混凝土(INTA){};
};
结构ConcreteSecond:接口
{
第二(inta,intb){};
};
int main(){
工厂;
工厂注册类型(“混凝土”);
工厂注册类型(“第二种混凝土”);
断言(factory.create(“concrete”,1)!=nullptr);
断言(factory.create(“concrete”)==nullptr);
断言(factory.create(“second_-concrete”,1)=nullptr);
断言(factory.create(“second_-concrete”,1,2)!=nullptr);
}

为了便于将来参考,同质的对立面是异质Hey Seth,根据《韦氏词典》的规定,“不同质”也是一个有效的词,其含义与“异质”相似。我选择前者是因为这也是Boost.Function/Factory文档的选择(参见我文章中的链接)。是的,我知道,你可以在几乎任何单词中添加“in”或“un”,它仍然是一个单词。萨尔曼:我看到的《韦氏词典》的参考文献越多,我就越觉得它是一堆垃圾。下次,试试牛津英语词典。@DeadMG我不在乎你对词典选择的看法。这与原来的问题无关。任何一个词的选择都已经足够了。然而,如果出于风格上的原因,一个比另一个更受欢迎,那我也没问题。但是请不要把这变成一个关于语言词典的讨论,它会很快退化为关于搜索引擎结果等的讨论。请坚持这个问题。谢谢我当然考虑过类似的选择。。。i、 e.将JSON对象传递给静态工厂函数,并让它返回实例。问题是,我正在处理的代码库目前有100多个这样的类,而且还在增长。因此,虽然这肯定是一个可能的解决方案,但我现在不太愿意称之为理想的解决方案。谢谢@bjorn&selbie。对于我的用例,最好的答案是代码生成。我的代码生成器是大约100行Python代码,生成大约有效的工厂函数。也就是说,我必须处理一些生成的代码。即使使用了一个不太完美的代码生成器,我在完成这项任务方面还是取得了令人难以置信的成效。对于我的用例,可能仍然值得扩展Boost.Functional/Factory。待以后探讨。:)FI:C++头解析库:适合m