夏天/isummer

Sun of my life !Talk is cheap, Show me the code! 追风赶月莫停留,平芜尽处是春山~

博客园 首页 新随笔 联系 管理

23 DesignPatterns学习笔记:C++语言实现 --- 1.5 Prototype

2016-07-21

(www.cnblogs.com/icmzn)


模式理解

1. Prototype  原型模式定义
    提供了类的自我复制的能力,即通过已有对象进行新对象的创建。因为原型模式实在内存中进行二进制流的拷贝,
所以比直接通过new 一个对象性能好。不同的实现方式与具体的语言相关。

2. 原型模式的优点
(1)性能优良,实在内存中基于二进制的拷贝
(2)在进行原型模式的时候,并不通过构造函数。

3. 原型模式的适用场景
(1)需要根据已有对象创建大量的对象;
(2)某个对象的创建需要有大量的前期准备,需要等待其他模块准备完毕;
(3)把相同的对象付给其他对象处理。

4. 原型模式的讨论与注意问题
(1)原型模式注意浅层拷贝与深层拷贝
    语言基础类型浅层拷贝,指针、引用浅层拷贝只传递地址内容需要注意
    C++:需要依赖类的复制构造函数实现
(2)这就是需要提到对象的复制问题

* 类成员是new 多态创建的类成员,要进行深层拷贝,同时要在~XX析构函数中进行析构处理。
* 当记性赋值操作是即=(),右边是一个临时由于运算产生的临时对象,则可以执行高效的赋值操作,即将成员指正直接指向“临时对象”内的成员地址位置,
然后,将“临时对象”的成员指针设置为nullptr,即可。《移动赋值构造》
 原型:
 CXXObject(const CXXObject && LinShi)
  {//移动构造函数
    m_pName = Linshi.m_pName;
    LinShi.m_pName = nullptr;

  }
 (3)实际上,Prototype, Builder, Abstract Factory都是通过一个类(对象) 来创建其他类
但是,他们之间有侧重之分。
builder 侧重对象的构建过程,并不直接返回类对象,由监管者Director协调具体的Builder类分别根据不同的构建过程创建对象;
Abstract Factory 侧重于具体的工厂创建本类型的不同对象,并且是直接返回对象;
Prototye 侧重根据一个对象返回这个对象的副本,必须注意深度拷贝。
 

 


 程序实现(C++)

 Prototype.h

 1 #pragma once
 2 
 3 #include <string>
 4 #include <iostream>
 5 #include <vector>
 6 class CAbsPrototype
 7 {
 8 public:
 9     CAbsPrototype();
10     ~CAbsPrototype();
11 public:
12     virtual CAbsPrototype* clone() const;
13 };
14 
15 
16 class CConcentPrototype : public CAbsPrototype
17 {
18 private:
19     //语言基础类型浅层拷贝,指针、引用浅层拷贝只传递地址内容需要注意
20     int m_iAge;
21     char* m_pName;//深层拷贝,构造冲初始化,系统中保持协调洗头
22     std::vector<double> m_dScores;
23 
24 
25 public:
26     // 注意,没有默认值得形参需要排在有默认值的前面,必然的原因
27     CConcentPrototype(const std::vector<double>& socresV, const char* aName = "Default Name", int age = 18) :m_iAge(age)
28     {
29         m_pName = nullptr;
30 
31         int l = strlen(aName) + 1;
32         m_pName = new char[l];
33         strcpy_s(m_pName, l, aName);
34 
35         //m_dScores.reserve(socresV.size());
36         m_dScores = socresV;
37         std::cout << "一般构造函数执行。" << std::endl;
38     }
39     ~CConcentPrototype()
40     {
41         delete[] m_pName;
42     }
43     CConcentPrototype(const CConcentPrototype& obj)//复制构造函数
44     {
45         m_iAge = obj.m_iAge;
46 
47         int l = strlen(obj.m_pName) + 1;
48         m_pName = new char[l];
49         strcpy_s(m_pName, l, obj.m_pName);
50 
51         m_dScores.clear();
52         m_dScores = obj.m_dScores;
53         std::cout << "复制构造函数执行。" << std::endl;
54     }
55     //要考虑深层拷贝与浅层拷贝
56     CAbsPrototype* clone() const override;
57     void outPut()
58     {
59         std::cout << m_pName << m_iAge << "  score:";
60 
61         for (auto t : m_dScores)
62             std::cout << t << "   ";
63             std::cout << std::endl;
64     }
65 
66 };

Prototype.cpp

 1 #include "AbsPrototype.h"
 2 
 3 
 4 CAbsPrototype::CAbsPrototype()
 5 {
 6 }
 7 CAbsPrototype::~CAbsPrototype()
 8 {
 9 }
10 
11 CAbsPrototype* CAbsPrototype::clone() const
12 {
13     return nullptr;
14 }
15 
16 
17 //
18 CAbsPrototype* CConcentPrototype::clone() const
19 {
20     //利用复制搞糟函数实现 Prototype 模式
21     CConcentPrototype* p = new CConcentPrototype(*this);
22     return p;
23     //子类指针,赋值给父类指针,在调用处转化为子类指针
24 }

 


(1)模板应用

main.cpp

 

 1 // Prototype.cpp : 定义控制台应用程序的入口点。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include "AbsPrototype.h"
 6 #include <iostream>
 7 
 8 
 9 int _tmain(int argc, _TCHAR* argv[])
10 {
11     std::vector<double> scores{11.2, 33.4, 45.6, 99.9};
12     CConcentPrototype* pObj = new CConcentPrototype(scores, "zhongguo", 26);
13     pObj->outPut();
14 
15     std::cout << "-----------------" << std::endl;
16     for (int i = 0; i < 10; i++)
17     {
18         CConcentPrototype* pTem = (CConcentPrototype*)pObj->clone();
19         pTem->outPut();
20     }
21 
22     system("pause");
23     return 0;
24 }

 

 

 

(2)输出展示

 

 

posted on 2016-07-21 23:14  夏天/isummer  阅读(296)  评论(0编辑  收藏  举报