创建型模式 原型模式

 

创建型模式 原型模式_原型模式

 

原型模式主要面对的问题是:“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。

适用情况:  一个复杂对象,具有自我复制功能,统一一套接口。 

 

/**
 * 创建型模式 原型模式
 * Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。
 * 使用Prototype模式创建的实例,具有与原型一样的数据。  
 * 1)由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。 
 * 2)目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。 
 * 3)根据对象克隆深度层次的不同,有浅度克隆与深度克隆。
 *
 */

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string>

class Person
{
public:
    virtual Person *Clone() = 0;
    virtual void pritT() = 0;
    virtual ~Person() {}
};

class CPlusPlusProgrammer: public Person
{
public:
    CPlusPlusProgrammer()
    {
        this->m_name = "";
        this->m_age = 0;
        this->m_resume = nullptr;
    }
    CPlusPlusProgrammer(std::string name, int age)
    {
        this->m_name = name;
        this->m_age = age;
        m_resume = nullptr;
    }
    ~CPlusPlusProgrammer()
    {
        if (m_resume != nullptr)
        {
            delete m_resume;
            m_resume = nullptr;
        }
    }
    // 这里解决深拷贝的问题,有两种方式
    // 1): 自定义CPlusPlusProgrammer类的拷贝构造函数和重载赋值运算符函数,在其函数内部对指针指向的内存区域进行拷贝处理。
    // 2): 仅仅只是在Clone里面,对指针指向的内存区域进行拷贝处理。
    virtual Person *Clone() override
    {
        CPlusPlusProgrammer *p = new CPlusPlusProgrammer;
        *p = *this;
        if (p->m_resume != nullptr) // 对指针指向的内存区域进行拷贝处理
        {
            p->m_resume = nullptr;
            p->m_resume = new char[strlen(this->m_resume)+1];
            strcpy(p->m_resume, this->m_resume);
        }
        return p;
    }
    void setResume(char *resume)
    {
        if ( m_resume != nullptr )
        {
            delete m_resume;
            m_resume = nullptr;
        }
        m_resume = new char[strlen(resume)+1];
        strcpy(m_resume, resume);
    }
    virtual void pritT() override
    {
        std::cout << "m_name: " << m_name << "\t" << "m_age: " << m_age << std::endl;
        if (m_resume != nullptr)
        {
            std::cout << "m_resume address: " << (void *)m_resume << "\t" << "m_resume value: " << m_resume << std::endl;
        } else 
        {
            std::cout << "m_resume: " << "nullptr" << std::endl;
        }
    }

private:
    std::string m_name;
    int m_age;
    char * m_resume;
};


void mytest()
{
    CPlusPlusProgrammer cplusplus1("小三", 21);
    cplusplus1.setResume("I'am cplusplus programmer");
    Person *p2 = cplusplus1.Clone(); // 对象具有自我复制功能 注意深拷贝和浅拷贝问题
    cplusplus1.pritT();
    p2->pritT();

    return;
}


int main()
{
    mytest();

    system("pause");
    return 0;
}