原型模式(C++实现)

(本博客旨在个人总结回顾)

1、详情:

原型模式:用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。

说明:

根据定义原型模式是通过拷贝一个现有对象生成新对象的,这样可以直接拷贝某个状态下的新对象,减少了对象的初始化和对该状态下对象的赋值,提高效率。

②原型模式与拷贝构造函数,赋值运算符重载函数的关系:原型模式通俗讲就是克隆,复制一个新的对象。而拷贝构造函数和赋值运算符重载函数可以实现这样的对象复制,所以他们可以是原型模式,但复制一个对象的方法有很多种,也就是说,原型模式是实现对象复制的一种模式,而拷贝构造函数和运算符重载函数可以按照原型模式来实现。

使用场景: ①资源优化场景。 ②类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。 ③性能和安全要求的场景。 ④通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 ⑤一个对象多个修改者的场景

优点:①性能提高。

缺点: 配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。

2、应用实例:

个人资料拷贝(使用简单例子易于理解)

3.1、UML类图:

3.2、例子源码

stdafx.h

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>
#include <iostream>
using namespace std;

// TODO:  在此处引用程序需要的其他头文件

Proto.h

#pragma once
class Proto
{
public:
    Proto();
    virtual ~Proto();

public:
    virtual void    display() = 0;
    virtual void    setPerson(int age, char* name) = 0;
    virtual Proto*  clone() = 0;
};

Proto.cpp

#include "stdafx.h"
#include "Proto.h"

Proto::Proto()
{
}

Proto::~Proto()
{
}

Person.h

#pragma once
#include "Proto.h"
class Person :
    public Proto
{
public:
    Person();
    ~Person();

public:
    Proto*  clone();
    void    setPerson(int age, char* name);
    void    display();

private:
    char*   m_strName;
    int     m_nAge;
};

Person.cpp

#include "stdafx.h"
#include "Person.h"
#include <string.h>
#include <cstdlib>
#include <cstdio>

Person::Person()
    : m_strName(NULL)
    , m_nAge(0)
{
}

Person::~Person()
{
}

Proto* Person::clone()
{
    Person* pPerson = new Person();
    pPerson->setPerson(m_nAge, m_strName);
    return pPerson;
}

void Person::setPerson(int age, char* name)
{
    m_nAge = age;
    if (NULL == m_strName)
    {
        m_strName = new char[strlen(name) + 1];
    }        
    else
    {
        delete m_strName;
        m_strName = new char[strlen(name) + 1];
    }
    strcpy_s(m_strName, strlen(name) + 1, name);
}

void Person::display()
{
    cout << "name:" << m_strName << endl << "age:" << m_nAge << endl;
}

ProtoPatternMemo.cpp

// ProtoPatternMemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "Person.h"


int _tmain(int argc, _TCHAR* argv[])
{
    Person person;
    person.setPerson(26, "王思聪");

    Proto* pPerson1 = person.clone();
    Proto* pPerson2 = pPerson1->clone();

    pPerson1->setPerson(67, "王健林");
    pPerson2->setPerson(36, "林二狗");
    person.display();
    pPerson1->display();
    pPerson2->display();

    delete pPerson1;
    pPerson1 = NULL;
    delete pPerson2;
    pPerson2 = NULL;

    system("pause");
    return 0;
}

3.3、运行结果:

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
原型模式是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而不必提供一个显式的构造函数。这种模式用于创建重复的对象,同时保持性能。在 C++ 中,原型模式通常通过实现 clone() 函数来实现。 以下是一个简单的原型模式示例: ```c++ #include <iostream> class Prototype { public: virtual ~Prototype() {} virtual Prototype* clone() const = 0; }; class ConcretePrototype : public Prototype { public: ConcretePrototype(int value) : m_value(value) {} ConcretePrototype(const ConcretePrototype& other) : m_value(other.m_value) {} virtual ConcretePrototype* clone() const override { return new ConcretePrototype(*this); } int getValue() const { return m_value; } private: int m_value; }; int main() { ConcretePrototype prototype(42); ConcretePrototype* clone = prototype.clone(); std::cout << "Original: " << prototype.getValue() << std::endl; std::cout << "Clone: " << clone->getValue() << std::endl; delete clone; return 0; } ``` 在上面的示例中,我们定义了一个抽象基类 `Prototype`,它有一个纯虚函数 `clone()`,所有的具体原型类都必须实现此函数。我们还定义了一个具体原型类 `ConcretePrototype`,它实现了 `clone()` 函数以复制自身。在 `main()` 函数中,我们首先创建了一个 `ConcretePrototype` 对象,并通过调用 `clone()` 函数来创建一个新的克隆对象。最后,我们输出了原型对象和克隆对象的值,并在程序结束时释放了克隆对象的内存。 需要注意的是,克隆函数应该返回一个指向新创建对象的指针,因为克隆对象通常需要在堆上分配内存。此外,由于克隆函数通常需要访问私有成员变量,因此它应该是原型类的友元函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值