原型模式主要面对的问题是:“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。
适用情况: 一个复杂对象,具有自我复制功能,统一一套接口。
/** * 创建型模式 原型模式 * 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; }