加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 如何使用Factory设计模式处理不同长度的构造函数?

发布时间:2020-12-16 07:13:06 所属栏目:百科 来源:网络整理
导读:我希望有一个类根据我传递的字符串创建不同种类的对象.根据我的研究,这最好地描述了工厂设计模式.我正在成功实现它,但我遇到了一个设计问题:我不知道如何创建具有不同长度构造函数的对象. 我们以一个名为Pet的抽象父类为例.从它有3个孩子:鱼,猫和狗.它们都
我希望有一个类根据我传递的字符串创建不同种类的对象.根据我的研究,这最好地描述了工厂设计模式.我正在成功实现它,但我遇到了一个设计问题:我不知道如何创建具有不同长度构造函数的对象.

我们以一个名为Pet的抽象父类为例.从它有3个孩子:鱼,猫和狗.它们都继承了Pet的重量和颜色,所以它们都在它们的构造中.但是鱼可能想要一些鱼鳍和一个关于它是否是咸水鱼的布尔值.这是一个4参数构造函数.猫想要多少条腿.这是3个参数.对于5个参数,狗可能有腿,品种的参数,以及他是否与其他狗一起运动良好.

在C中,我理解没有任何反射,所以最常见的做法似乎只是声明一个字符串到函数指针的映射,其中函数指针指向一个看起来像这样的函数:

template<typename T> Pet* createObject(int weight,std::string color) {return new T(weight,color);}

同样,我不确定如何在不影响其他对象构造函数的调用的情况下将更多参数填充到调用中.

我可以想到两个解决方法:使新函数接受不同数量的参数或使构造函数的默认参数超过一定的大小.

解决方法1似乎有点过分取决于我有多少不同的参数大小.

解决方法2似乎忽略了构造函数的整个要点,因为在调用构造函数之后我将被强制分配数据.

还有其他更好的解决方法吗?

解决方法

您可以使用可变参数模板和完美转发.

template<typename T,typename... Args>
Pet* createObject(Args&&... args) {
    return new T(std::forward<Args>(args)...);
}

但是,由于任何指针都可以转换为其基类,因此如果此函数返回T *可能会更好.此外,使用裸指针并不明智,因为您必须手动删除它们.最好使用shared_ptrunique_ptr.对于这些类,已经有类似的工厂方法:make_sharedmake_unique(后者仅在C 14中).或者,如果您的编译器不支持C 11,那么您可以使用Boost中的shared_ptr和make_shared.

当然,当你在编译时知道你需要创建什么类型时,这个解决方案是有效的.如果你必须在运行时决定它,那么整个问题必须从不同的方向考虑,好像你不知道你要创建什么类型,那么你无法知道给它们的参数,除了所有类型的通用参数.在这种情况下,你需要的是一个abstract factory pattern.幸运的是,C(至少从C 11开始)提供了一种实现这种模式的方法,而不需要创建很多类.例如,假设你必须创建一些派生自Pet的类的实例.实际种类的宠物,它的大小和其他属性在其他地方决定,而宠物的名字在创建时决定.然后,你需要一个像这样的工厂:

typedef std::function<std::shared_ptr<Pet>(const std::string& name)> PetFactory;

在某些时候,你决定要创建一个狗(我将实际创建参数的含义留给你的想象).

PetFactory petFactory =
        [](const std::string& name) {
            return std::make_shared<Dog>(name,12,"brown",23.5);
        }

实际创建它时,您只需要调用工厂:

std::shared_ptr<Pet> pet = petFactory("Pet Name");

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读