服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++工厂方法之对象创建型模式详解

C++工厂方法之对象创建型模式详解

2022-10-17 13:24早睡身体好hh C/C++

这篇文章主要为大家详细介绍了C++对象创建型模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

1.代码示例

工厂方法模式,简称工厂模式或者多态工厂模式。与简单工厂模式相比,引入了更多的新类,灵活性更强,实现也更加复杂。符合开闭原则,付出的代价是需要新增加多个新的工厂类。

如下,M_UndeadFactoryM_ElementFactoryM_MechanicFactory 类有一个共同的父类 M_ParFactory(工厂抽象类)。

M_ParFactory 类中的 createMonster 成员函数其实就是个工厂方法,工厂方法模式的名字也是由此而来。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <iostream>
using namespace std;
// 怪物父类
class Monster
{
public:
    // 构造函数
    Monster(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {}
    virtual ~Monster() {} // 父类的析构函数应该为虚函数
protected: // 可能被子类访问的成员,所以用protected修饰
    int m_life; // 生命值
    int m_magic; // 魔法值
    int m_attack; // 攻击力
};
// 亡灵类怪物
class M_Undead : public Monster
{
public:
    // 构造函数
    M_Undead(int life, int magic, int attack) : Monster(life, magic, attack)
    {
        cout << "一个亡灵类怪物来到了这个世界" << endl;
    }
    // 其他代码略
};
// 元素类怪物
class M_Element : public Monster
{
public:
    // 构造函数
    M_Element(int life, int magic, int attack) : Monster(life, magic, attack)
    {
        cout << "一个元素类怪物来到了这个世界" << endl;
    }
    // 其他代码略
};
// 机械类怪物
class M_Mechanic : public Monster
{
public:
    // 构造函数
    M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack)
    {
        cout << "一个机械类怪物来到了这个世界" << endl;
    }
    // 其他代码略
};
// 所有工厂类的父类
class M_ParFactory
{
public:
    virtual Monster* createMonster() = 0; // 具体实现在子类中进行
    virtual ~M_ParFactory() {} // 父类的析构函数应该为虚函数
};
// M_Undead怪物类型的工厂,生产M_Undead类型怪物
class M_UndeadFactory : public M_ParFactory
{
public:
    virtual Monster* createMonster()
    {
        Monster *ptmp = new M_Undead(300, 50, 80); // 创建亡灵类怪物
        //这里可以增加一些其他业务代码
        return ptmp;
    }
};
// M_Element怪物类型的工厂,生产M_Element类型怪物
class M_ElementFactory : public M_ParFactory
{
public:
    virtual Monster* createMonster()
    {
        return new M_Element(200, 80, 100); // 创建元素类怪物
    }
};
// M_Mechanic怪物类型的工厂,生产M_Mechanic类型怪物
class M_MechanicFactory : public M_ParFactory
{
public:
    virtual Monster* createMonster()
    {
        return new M_Mechanic(400, 0, 110); // 创建机械类怪物
    }
};
// 全局函数:用于创建怪物对象
// 注意:形参的类型是工厂父类类型的指针,返回类型是怪物父类类型的指针
Monster* Gbl_CreateMonster(M_ParFactory* factory)
{
    return factory->createMonster();
    // createMonster虚函数扮演了多态new的行为,factory指向的具体怪物工厂类不同,创建的怪物对象也不同
}
int main()
{
    M_ParFactory* p_ud_fy = new M_UndeadFactory(); // 多态工厂,注意指针类型
    Monster* pM1 = Gbl_CreateMonster(p_ud_fy); // 产生了一只亡灵类怪物,也是多态,注意返回类型
    // 当然,这里也可以直接写成 Monster *pM1 = p_ud_fy->createMonster();
    M_ParFactory* p_elm_fy = new M_ElementFactory();
    Monster *pM2 = Gbl_CreateMonster(p_elm_fy); // 产生了一只元素类怪物
    M_ParFactory* p_mec_fy = new M_MechanicFactory();
    Monster* pM3 = Gbl_CreateMonster(p_mec_fy); // 产生了一只机械类怪物
    // 释放工厂
    delete p_ud_fy;
    delete p_elm_fy;
    delete p_mec_fy;
    // 释放怪物
    delete pM1;
    delete pM2;
    delete pM3;
    return 0;
}

简单工厂模式把创建对象这件事放到了一个统一的地方来处理,弹性比较差。而工厂方法模式相当于建立了一个程序实现框架,从而让子类来决定对象如何创建。

工厂方法模式往往需要创建一个与产品等级结构(层次)相同的工厂等级结构,这也增加了新类的层次结构和数目。

如果不想创建太多工厂类,又想封装变化,则可以创建怪物工厂子类模板。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
using namespace std;
// 怪物父类
class Monster
{
public:
    // 构造函数
    Monster(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {}
    virtual ~Monster() {} // 父类的析构函数应该为虚函数
protected: // 可能被子类访问的成员,所以用protected修饰
    int m_life; // 生命值
    int m_magic; // 魔法值
    int m_attack; // 攻击力
};
// 亡灵类怪物
class M_Undead : public Monster
{
public:
    // 构造函数
    M_Undead(int life, int magic, int attack) : Monster(life, magic, attack)
    {
        cout << "一个亡灵类怪物来到了这个世界" << endl;
    }
    // 其他代码略
};
// 元素类怪物
class M_Element : public Monster
{
public:
    // 构造函数
    M_Element(int life, int magic, int attack) : Monster(life, magic, attack)
    {
        cout << "一个元素类怪物来到了这个世界" << endl;
    }
    // 其他代码略
};
// 机械类怪物
class M_Mechanic : public Monster
{
public:
    // 构造函数
    M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack)
    {
        cout << "一个机械类怪物来到了这个世界" << endl;
    }
    // 其他代码略
};
// 所有工厂类的父类
class M_ParFactory
{
public:
    virtual Monster* createMonster() = 0; // 具体实现在子类中进行
    virtual ~M_ParFactory() {} // 父类的析构函数应该为虚函数
};
template <typename T>
class M_ChildFactory :public M_ParFactory
{
public:
    virtual Monster* createMonster()
    {
        return new T(300, 50, 80); //如果需要不同的值则可以通过createMonster的形参将值传递进来
    }
};
int main()
{
    M_ChildFactory<M_Undead> myFactory;
    Monster* pM10 = myFactory.createMonster();
    // 释放资源
    delete pM10;
    getchar();
    return 0;
}

UML 如下:

C++工厂方法之对象创建型模式详解

2.工厂方法模式的定义(实现意图)

定义一个用于创建对象的接口(M_ParFactory类中的createMonster成员函数),由子类(M_UndeadFactoryM_ElementFactoryM_MechanicFactory)决定要实例化的类是哪一个。该模式使得某个类(M_UndeadM_ElementM_Mechanic)的实例化延迟到子类(M_UndeadFactoryM_ElementFactoryM_MechanicFactory)。

一般可以认为,将简单工厂模式的代码经过把工厂类进行抽象改造成符合开闭原则后的代码,就变成了工厂方法模式的代码。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!  

原文链接:https://blog.csdn.net/qq_42815188/article/details/123381221

延伸 · 阅读

精彩推荐
  • C/C++C语言 main 函数详情

    C语言 main 函数详情

    这篇文章主要介绍C语言 main 函数,文章将围绕C语言 main 函数相关资料详细展开,需要的朋友可以参考一下...

    黄裕玲6522022-01-25
  • C/C++C语言strlen和sizeof在数组中的使用详解

    C语言strlen和sizeof在数组中的使用详解

    对于 strlen 和 sizeof,相信不少程序员会混淆其功能。虽然从表面上看它们都可以求字符串的长度,但二者却存在着许多不同之处及本质区别...

    执久呀7182022-01-21
  • C/C++C语言不用链表完成学生管理系统(完整代码)

    C语言不用链表完成学生管理系统(完整代码)

    这篇文章主要介绍了C语言不用链表完成学生管理系统(完整代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,...

    Waterpaddler6572021-11-01
  • C/C++C++ 手把手教你实现可变长的数组实现

    C++ 手把手教你实现可变长的数组实现

    这篇文章主要介绍了C++ 手把手教你实现可变长的数组实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

    小林coding6082021-08-06
  • C/C++C/C++利用libxml2高效输出XML大文件详解

    C/C++利用libxml2高效输出XML大文件详解

    这篇文章主要给大家介绍了关于C/C++利用libxml2高效输出XML大文件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学...

    infoworld9612021-06-10
  • C/C++实例代码分析c++动态分配

    实例代码分析c++动态分配

    这篇文章主要介绍了c++动态分配的的相关资料,文中代码简单易懂,方便大家更好的学习参考,感兴趣的朋友可以了解下...

    晟夏的叶9992021-09-09
  • C/C++C语言各种操作符透彻理解上篇

    C语言各种操作符透彻理解上篇

    C 语言提供了丰富的操作符,有:算术操作符,移位操作符,位操作符,赋值操作符。让我们通读本篇来详细了解吧...

    七忆岁和6612022-09-15
  • C/C++C语言修炼之路灵根孕育源流出 初识C言大道生上篇

    C语言修炼之路灵根孕育源流出 初识C言大道生上篇

    C语言是一门面向过程、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以...

    玄澈_6622022-10-11