模式
在一定环境中解决某一问题的方案,包括三个基本元素--问题,解决方案和环境。
大白话:在一定环境下,用固定套路解决问题。
设计模式(Design pattern)
是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
设计模式的分类(Gang of Four的“DesignPatterns: Elements of Resualbel Software”书将设计模式归纳为三大类型,共23种)
创建型模式 : 通常和对象的创建有关,涉及到对象实例化的方式。(共5种模式)
结构型模式: 描述的是如何组合类和对象以获得更大的结构。(共7种模式)
行为型模式: 用来对类或对象怎样交互和怎样分配职责进行描述。(共11种模式)
创建型模式用来处理对象的创建过程,主要包含以下5种设计模式:
1: 单例模式(Singleton Pattern)是保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2: 工厂模式(Factory Method Pattern)的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。
3: 抽象工厂模式(Abstract Factory Pattern)的意图是提供一个创建一系列相关或者相互依赖的接口,而无需指定它们具体的类。
4: 建造者模式(Builder Pattern)的意图是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
5: 原型模式(Prototype Pattern)是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
1.单例模式
代码1:
#include <iostream> using namespace std; ////////////////////////////////////////////////////////////////////////// //单例模式就是把“构造函数私有化”,就不能在类外构造对象了,只能在类里面调用构造函数,创建对象,让后通静态变量返回对象 //------------单例模式(懒汉式)-------------------- /*所谓的懒汉式:就是在需要的使用对象的时候再创建对象的实例。就是当调用函数时,才创建类的对象。*/ class Singleton_lazy { private: Singleton_lazy() { cout << "Singleton_lazy 构造函数" << endl; } public: static Singleton_lazy* getInstance() { //判断是否为空,用来限制创建单个实例(就是在此处限制只能产生单个实例) if (m_pSingleton == NULL) { //如果不为空,开辟空间,返回指针(使用new时,会自动调用构造函数) m_pSingleton = new Singleton_lazy; //创建类的对象 } return m_pSingleton; } static void freeInstance() { if (m_pSingleton != NULL) { //“指针变量”和指针所“指向的内存空间”是两个不同的概念 delete m_pSingleton; //释放所指向的内存空间 m_pSingleton = NULL; //让指指向NULL } } private: static Singleton_lazy *m_pSingleton; int temp; }; int globleVar = 10; //静态成员的初始化 Singleton_lazy* Singleton_lazy::m_pSingleton = NULL; ////////////////////////////////////////////////////////////////////////// //------------单例模式(饿汉式)-------------------- class Singleton_hungry { private: Singleton_hungry() { cout << "Singleton_hungry 构造函数" << endl; } public: static Singleton_hungry* getInstance() { return m_pSingleton_h; } static void freeInstance() { if (m_pSingleton_h != NULL) { delete m_pSingleton_h; m_pSingleton_h = NULL; } } private: static Singleton_hungry* m_pSingleton_h; int temp; }; /*☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ 全局变量优先于main函数,所以输出结果是先显示“pSingleton1和pSingleton2是一个实例” 这也是饿汉模式的原理:就是静态变量在类外面初始化,并且在类的声明的下面。 在编译的时候,先给类开辟空间,然后给全局变量开辟空间,并给全局变量初始化。 全局变量调用类的构造,构造一个对象,然后开始进入main函数,执行main函数体。 ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆*/ //饿汉式和懒汉式不同的地方。就是静态变量先new 一个对象,全局变量的初始化优先于main函数执行。所以先显示“pSingleton1和pSingleton2是一个实例” Singleton_hungry* Singleton_hungry::m_pSingleton_h = new Singleton_hungry; int main() { //------------------------懒汉式-------------------------------- Singleton_lazy *pSingleton1 = Singleton_lazy::getInstance(); Singleton_lazy *pSingleton2 = Singleton_lazy::getInstance(); if (pSingleton1 == pSingleton2) { cout << "pSingleton1和pSingleton2是一个实例" << endl; } else { cout << "pSingleton1和pSingleton2不是同一个实例" << endl; } Singleton_lazy::freeInstance(); //-------------------------饿汉式------------------------------------ Singleton_hungry *pSingleton_h1 = Singleton_hungry::getInstance(); Singleton_hungry *pSingleton_h2 = Singleton_hungry::getInstance(); if (pSingleton_h1 == pSingleton_h2) { cout << "pSingleton_h1和pSingleton_h2是同一个实例" << endl; } else { cout << "pSingleton_h1和pSingleton_h2不是同一个实例" << endl; } Singleton_hungry::freeInstance(); system("pause"); }
懒汉式单实例和多线程问题
代码2:
<span style="font-size:14px;">#include "stdafx.h" #include "windows.h" #include "winbase.h" #include "afxmt.h" #include <process.h> #include <stdlib.h> #include <iostream> using namespace std; /*☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆ 懒汉模式和多线程结合时,当在构造函数中Sleep 时,当一个线程创建对象并进入构造函数时, 会先把线程挂起,然后下一个线程再次创建对象并进入构造函数时,也会挂起线程,此时, 每个线程判定m_p_t都是NULL,这样会导致创建多个对象。也就是每个线程都会创建一个类的对象, 这就变成多实例,而不是单实例,同时还会出现资源共享的情况,可能出现资源锁。 也就是抢占资源,会造成程序的输出不确定的结果。这就是线程间的同步问题。 为了保证线程的同步,可以使用临界区技术。(还可以使用互斥量、信号量) 就是把线程共享的部分锁定,保证相同的部分每次都只有一个线程进行操作。 临界区(Critical Section)。临界区对象通过提供一个进程内所有线程必须 共享的对象来控制线程。只有拥有那个对象的线程可以访问保护资源。在另一个线 程可以访问该资源之前,前一个线程必须释放临界区对象,以便新的线程可以索取 对象的访问权。 互斥量(Mutex Semaphore)。互斥量的工作方式非常类似于临界区,只是 互斥量不仅保护一个进程内为多个线程使用的共享资源,而且还可以保护系统中两 个或多个进程之间的的共享资源。 信号量(Semaphore)。信号量可以允许一个或有限个线程访问共享资源。 它是通过计数器来实现的,初始化时赋予计数器以可用资源数,当将信号量提供给 一个线程时,计数器的值减1,当一个线程释放它时,计数器值加1。当计数器值小 于等于0时,相应线程必须等待。信号量是Windows98同步系统的核心。从本质上 讲,互斥量是信号量的一种特殊形式。 ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆*/ class Singleton_lazy_thread { private: Singleton_lazy_thread() { cout << "Singleton_lazy_thread() 构造函数begin\n"; Sleep(1000); cout << "Singleton_lazy_thread() 构造函数end\n"; } public: static Singleton_lazy_thread* getInstance() { if (m_p_t == NULL) { count++; m_p_t=new Singleton_lazy_thread; } return m_p_t; } static void freeInstance() { if (m_p_t != NULL) { delete m_p_t; m_p_t = NULL; } } static void printS() //测试函数 { cout << "Singleton_lazy_thread printS test" << endl; } private: static Singleton_lazy_thread* m_p_t; static int count; int temp; }; Singleton_lazy_thread* Singleton_lazy_thread::m_p_t = NULL; int Singleton_lazy_thread::count = 0; void MyThreadFunc(void *) { //cout << "我是线程体 ...." << endl; cout << "我是线程体 ....\n"; Singleton_lazy_thread::getInstance()->printS(); } ////////////////////////////////////////////////////////////////////////// /*--------------------------使用临界区技术(锁定线程公共操作部分)-----------------------------*/ // 线程同步问题 //临界区 //类CCriticalSection的对象表示一个“临界区”,它是一个用于同步的对象, //同一时刻只允许一个线程存取资源或代码区。 //临界区在控制一次只有一个线程修改数据或其它的控制资源时非常有用。 //使用时必须包含头文件#include "afxmt.h" static CCriticalSection cs; class Singleton_lazy_thread_Sync { private: Singleton_lazy_thread_Sync() { //TRACE()宏一般是用在mfc中的,用于将调试信息输出到vs的输出窗口中(这是关键), //这在使用vs作为开发工具的时候,是非常方便的。 //TRACE("Singleton begin\n"); m_count++; cout << "Singleton_lazy_thread_Sync() 构造函数begin\n"; Sleep(1000); cout << "Singleton_lazy_thread_Sync() 构造函数end\n"; //TRACE("Singleton end\n"); } Singleton_lazy_thread_Sync(const Singleton_lazy_thread_Sync&); Singleton_lazy_thread_Sync& operator=(const Singleton_lazy_thread_Sync&); public: static Singleton_lazy_thread_Sync* getInstance() { if (m_p_t_Sync == NULL) //第一次检查看实例有没有被创建 { cs.Lock(); //只有当pInstance等于null时,才开始使用枷锁机制 二次检查 //第二个线程在创建时不知道第一个线程已经创建了, //所以在临界区检查,防止被多次创建(著名的二次检查) if (m_p_t_Sync == NULL) //double check 。第二次检查, { m_count++; m_p_t_Sync = new Singleton_lazy_thread_Sync; } cs.Unlock(); } return m_p_t_Sync; } static void freeInstance() { if (m_p_t_Sync != NULL) { delete m_p_t_Sync; m_p_t_Sync = NULL; } } static void printS() //测试函数 { cout << "Singleton_lazy_thread_Sync printS test" << endl; } static void printV() { //TRACE("printV..m_count:%d \n", m_count); cout << "printV..m_count:" << m_count << endl; } private: static Singleton_lazy_thread_Sync* m_p_t_Sync; static int m_count; int temp; }; Singleton_lazy_thread_Sync & Singleton_lazy_thread_Sync::operator=(const Singleton_lazy_thread_Sync &) { // TODO: 在此处插入 return 语句 } Singleton_lazy_thread_Sync* Singleton_lazy_thread_Sync::m_p_t_Sync = NULL; int Singleton_lazy_thread_Sync::m_count = 0; void MyThreadFuncSync(void *) { //cout << "我是线程体 ...." << endl; cout << "我是线程体 ....\n"; Singleton_lazy_thread_Sync::getInstance()->printV(); } int main() { HANDLE hThread1[10]; for (int i = 0; i < 3;i++) { hThread1[i] = (HANDLE)_beginthread(MyThreadFunc, 0, NULL); } for (int i = 0; i < 3;i++) { WaitForSingleObject(hThread1[i], INFINITE); } cout << "hello word" << endl; ////////////////////////////////////////////////////////////////////////// cout << "---------------线程同步问题---------------" << endl; int i = 0; DWORD dwThreadId[201], dwThrdParam = 1; HANDLE hThread[201]; int threadnum = 3; for (i = 0; i < threadnum; i++) { //hThread[i] = (HANDLE)_beginthreadex( NULL, 0, &threadfunc, NULL, 0,&dwThreadId[i] ); hThread[i] = (HANDLE)_beginthread(&MyThreadFuncSync, 0, 0); if (hThread[i] == NULL) { //TRACE("begin thread %d error!!!\n", i); printf("begin thread %d error!!!\n", i); break; } } for (i = 0; i < threadnum; i++) { WaitForSingleObject(hThread[i], INFINITE); } system("pause"); return 0; }
2.工厂模式
#include <iostream> #include <stdlib.h> using namespace std; class Fruit { public: virtual void getFruit() = 0; protected: private: }; class Banana:public Fruit { public: virtual void getFruit() { cout << "我是香蕉" << endl; } protected: private: }; class Apple :public Fruit { public: virtual void getFruit() { cout << "我是苹果" << endl; } protected: private: }; class Pear :public Fruit { public: virtual void getFruit() { cout << "我是梨" << endl; } protected: private: }; //--------------------------简单工厂模式。------------------------ //也就是所有的操作都是在类里面完成的,不符合设计模式的设计规则 //所以可以进行改进。 class Factory_Simple { public: Fruit* produceFruit(char* p) { if (strcmp(p, "banana") == 0) { return new Banana; } if (strcmp(p, "apple") == 0) { return new Apple; } if (strcmp(p, "pear") == 0) { return new Pear; } else { printf("不支持\n"); return NULL; } } protected: private: }; ////////////////////////////////////////////////////////////////////////// /* 改进后的工厂模式 为每个对象都产生一个单独的工厂,专门生产一种产品。 */ class Factory { public: virtual Fruit* produceFruit() = 0; protected: private: }; class BananaFactory:public Factory { public: //函数的返回值是一个父类的指针 virtual Fruit* produceFruit() { //函数体里面返回的是一个子类的指针 //通过父类的指针或者引用来调用子类的函数,实现多态 return new Banana; } protected: private: }; class AppleFactory:public Factory { public: virtual Fruit* produceFruit() { return new Apple; } protected: private: }; class PearFactory :public Factory { public: virtual Fruit* produceFruit() { return new Pear; } protected: private: }; int main() { cout << endl << "---------简单工厂模式---------" << endl; Fruit* fruit = NULL; Factory_Simple* factorySimple = new Factory_Simple; fruit = factorySimple->produceFruit("banana"); fruit->getFruit(); delete fruit; fruit = NULL; fruit = factorySimple->produceFruit("apple"); fruit->getFruit(); delete fruit; fruit = NULL; fruit = factorySimple->produceFruit("pear"); fruit->getFruit(); delete factorySimple; delete fruit; fruit = NULL; factorySimple = NULL; system("pause"); ////////////////////////////////////////////////////////////////////////// //改进后的工厂(工厂抽象成一个虚基类) cout << endl << "---------改进后的工厂模式---------" << endl; Factory *factory = NULL; factory = new BananaFactory; fruit = factory->produceFruit(); fruit->getFruit(); delete factory; delete fruit; fruit = NULL; factory = new AppleFactory; fruit = factory->produceFruit(); fruit->getFruit(); delete factory; delete fruit; fruit = NULL; factory = new PearFactory; fruit = factory->produceFruit(); fruit->getFruit(); delete factory; delete fruit; system("pause"); return 0; }
3.抽象工厂模式
#include <iostream> #include <stdlib.h> using namespace std; class Fruit { public: virtual void getFruitName() = 0; protected: private: }; class Banana :public Fruit { public: virtual void getFruitName() { cout << "香蕉" << endl; } protected: private: }; class Apple :public Fruit { public: virtual void getFruitName() { cout << "苹果" << endl; } protected: private: }; class Pear : public Fruit { public: virtual void getFruitName() { cout << "梨" << endl; } protected: private: }; class Mango : public Fruit { public: virtual void getFruitName() { cout << "芒果" << endl; } protected: private: }; ////////////////////////////////////////////////////////////////////////// //工厂模式只能生产一个产品。(要么香蕉、要么苹果) //抽象工厂可以一下生产一个“产品族”(里面有很多产品组成),就是可以生产多种产品。 //缺点是: //抽象工厂的缺点就是产品线写死了。 //如果需要添加新的产品,就需要在原来抽象类上改 ////////////////////////////////////////////////////////////////////////// class AbstractFactory { public: //抽象工厂的缺点就是产品线写死了。 //如果需要添加新的产品,就需要在原来抽象类上改 virtual Fruit* produceBanana() = 0; virtual Fruit* produceApple() = 0; virtual Fruit* producePear() = 0; virtual Fruit* produceMango() = 0; protected: private: }; class Factory : public AbstractFactory { public: virtual Fruit* produceApple() { return new Apple; } virtual Fruit* produceBanana() { return new Banana; } virtual Fruit* producePear() { return new Pear; } virtual Fruit* produceMango() { return new Mango; } protected: private: }; int main() { cout << "---------------抽象工厂模式---------------" << endl; Factory* factory = new Factory; Fruit* fruit = NULL; fruit = factory->produceApple(); fruit->getFruitName(); delete fruit; fruit = NULL; fruit = factory->produceBanana(); fruit->getFruitName(); delete fruit; fruit = NULL; fruit = factory->producePear(); fruit->getFruitName(); delete fruit; fruit = NULL; fruit = factory->produceMango(); fruit->getFruitName(); delete fruit; fruit = NULL; delete factory; factory = NULL; system("pause"); return 0; }
4.建造者模式
#include <iostream> #include <stdlib.h> #include <string> using namespace std; ////////////////////////////////////////////////////////////////////////// /* 1) Builder:为创建产品各个部分,统一抽象接口。 2) ConcreteBuilder:具体的创建产品的各个部分,部分A, 部分B,部分C。 3) Director:构造一个使用Builder接口的对象。 4) Product:表示被构造的复杂对象。 ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类, 包括将这些部件装配成最终产品的接口。 适用情况: 一个对象的构建比较复杂,将一个对象的构建(?)和对象的表示(?)进行分离。 建造者模式设计三个类对象(案例): 设计者(也叫指挥者)、 工程队(可以造别墅、平房、四合院等), 房子(有门、窗户、墙等) */ ////////////////////////////////////////////////////////////////////////// /////////////////////////////////建造者模式产生原因/////////////////////// class House_Previous { public: //set 属性 void setDoor(string door){ this->m_door = door; } void setWindow(string window){ this->m_window = window; } void setWall(string wall){ this->m_wall = wall; } //get 属性 string getDoor(){ cout << m_door << endl; return m_door; } string getWindow(){ cout << m_window << endl; return m_window; } string getWall(){ cout << m_wall << endl; return m_wall; } protected: private: string m_door; string m_window; string m_wall; }; class Builder_Previous { public: Builder_Previous() { this->m_house = new House_Previous; } void buildHouse() { buildDoor(); buildWindow(); buildWall(); } void buildDoor() { m_house->setDoor("门"); } void buildWindow() { m_house->setWindow("窗户"); } void buildWall() { m_house->setWall("墙壁"); } House_Previous* getHouse() { return m_house; } protected: private: House_Previous *m_house; }; ///////////////////////建造者模式///////////////////////////// /* 建造者模式设计三个类对象(案例): 设计者(也叫指挥者、主管)、------------------ class Director 主管类 工程队(可以造别墅、平房、四合院等),------ class Builder 工程队类 房子(有门、窗户、墙等)-------------------- class House 房子类 扩展: 设计师(指挥者) 负责建造逻辑。建筑队 干具体的活 再让设计师分三六九等,指挥三六九等建筑队,建造三六九等的房子 也就是可以把设计师在细化分类,建筑队也可以再细化分类,房子同样可以细化不同的房子。 就是“主管抽象、工程队抽象、房子抽象”。 */ class House { public: virtual void setDoor(string door){}; //虚函数必须有实现代码,纯虚函数可以没实现代码。 virtual void setWindow(string window){}; virtual void setWall(string wall){}; string getDoor(){ cout << m_door << endl; return m_door; }; string getWindow(){ cout << m_window << endl; return m_window; }; string getWall(){ cout << m_wall << endl; return m_wall; }; protected: string m_door; string m_window; string m_wall; private: }; //平房、公寓 class Flat :public House { public: virtual void setDoor(string door){ this->m_door = door; } virtual void setWindow(string window){ this->m_window = window; } virtual void setWall(string wall){ this->m_wall = wall; } protected: private: }; // 楼房 class Floor :public House { public: virtual void setDoor(string door){ this->m_door = door; } virtual void setWindow(string window){ this->m_window = window; } virtual void setWall(string wall){ this->m_wall = wall; } protected: private: }; // 别墅 class Villa :public House { public: virtual void setDoor(string door){ this->m_door = door; } virtual void setWindow(string window){ this->m_window = window; } virtual void setWall(string wall){ this->m_wall = wall; } protected: private: }; class Builder //建造者 { public: /*void buildHouse() { buildDoor(); buildWindow(); buildWall(); }*/ virtual void buildHouse() = 0; virtual void buildDoor() = 0; virtual void buildWindow() = 0; virtual void buildWall() = 0; protected: House *m_house; private: }; class SanDengBuilder : public Builder //三等builder { public: SanDengBuilder(House* house) { m_house = house; } virtual void buildHouse() { buildDoor(); buildWindow(); buildWall(); } virtual void buildDoor() { m_house->setDoor("三等门"); } virtual void buildWindow() { m_house->setWindow("三等窗户"); } virtual void buildWall() { m_house->setWall("三等墙壁"); } protected: private: }; class LiuDengBuilder : public Builder // 六等builder { public: LiuDengBuilder(House *house) { m_house = house; } virtual void buildHouse() { buildDoor(); buildWindow(); buildWall(); } virtual void buildDoor() { m_house->setDoor("六等门"); } virtual void buildWindow() { m_house->setWindow("六等窗户"); } virtual void buildWall() { m_house->setWall("六等墙壁"); } protected: private: }; class JiuDengBuilder : public Builder //九等builder { public: JiuDengBuilder(House *house) { m_house = house; } virtual void buildHouse() { buildDoor(); buildWindow(); buildWall(); } virtual void buildDoor() { m_house->setDoor("九等门"); } virtual void buildWindow() { m_house->setWindow("九等窗户"); } virtual void buildWall() { m_house->setWall("九等墙壁"); } protected: private: }; class Director { public: virtual void Construct() = 0; protected: Builder* m_builder; private: }; class SanDengDirector : public Director { public: SanDengDirector(Builder *builder) { m_builder = builder; } virtual void Construct() { m_builder->buildDoor(); m_builder->buildWindow(); m_builder->buildWall(); } protected: private: }; class LiuDengDirector : public Director { public: LiuDengDirector(Builder *builder) { m_builder = builder; } virtual void Construct() { m_builder->buildDoor(); m_builder->buildWindow(); m_builder->buildWall(); } protected: private: }; class JiuDengDirector : public Director { public: JiuDengDirector(Builder *builder) { m_builder = builder; } virtual void Construct() { m_builder->buildDoor(); m_builder->buildWindow(); m_builder->buildWall(); } protected: private: }; int main() { cout << "-----------------客户直接造房子-----------------" << endl; House_Previous *house_pre = new House_Previous; house_pre->setDoor("门"); house_pre->setWindow("窗户"); house_pre->setWall("墙壁"); house_pre->getDoor(); house_pre->getWindow(); house_pre->getWall(); delete house_pre; house_pre = NULL; cout << "-----------------工程队造房子-----------------" << endl; Builder_Previous *builder_Previous = new Builder_Previous; builder_Previous->buildDoor(); builder_Previous->buildWindow(); builder_Previous->buildWall(); house_pre = builder_Previous->getHouse(); house_pre->getDoor(); house_pre->getWindow(); house_pre->getWall(); delete house_pre; house_pre = NULL; delete builder_Previous; builder_Previous = NULL; cout << "---------------建造者模式------------------" << endl; //定义房子 Flat *flat = new Flat; //平房 Floor *floor = new Floor; //楼房 Villa *villa = new Villa; //别墅 //定义基类的指针 Director *director = NULL; Builder *builder = NULL; House* house = NULL; SanDengBuilder *sanBuilder = new SanDengBuilder(flat); LiuDengBuilder *liuBuilder = new LiuDengBuilder(floor); JiuDengBuilder *jiuBuilder = new JiuDengBuilder(villa); cout << "---------三等指挥,三等建造者,建设平房-------------" << endl; director = new SanDengDirector(sanBuilder); director->Construct(); flat->getDoor(); flat->getWindow(); flat->getWall(); cout << "---------三等指挥,三等建造者,建设楼房-------------" << endl; director = new SanDengDirector(liuBuilder); director->Construct(); floor->getDoor(); floor->getWindow(); floor->getWall(); cout << "---------三等指挥,三等建造者,建设别墅-------------" << endl; director = new SanDengDirector(jiuBuilder); director->Construct(); villa->getDoor(); villa->getWindow(); villa->getWall(); cout << endl << "因为new的太多,不再一个一个删除,先不用管内存泄露" << endl; system("pause"); return 0; }
5.原型模式
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <stdlib.h> #include <string> using namespace std; ////////////////////////////////////////////////////////////////////////// /* 原型模式 Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。 使用Prototype模式创建的实例,具有与原型一样的数据。 1)由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。 2)目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象, 不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。 3)根据对象克隆深度层次的不同,有浅度克隆与深度克隆。 其实原型模式就是返回一个和自己一模一样的类型的数据(深浅拷贝) */ ////////////////////////////////////////////////////////////////////////// class Person { public: virtual Person* clone() = 0; virtual void printT() = 0; protected: string m_name; int m_age; char *m_resume; private: }; class CPlusPlusProgrammer : public Person { public: CPlusPlusProgrammer() { m_name = ""; m_age = 0; m_resume = NULL; } CPlusPlusProgrammer(string name, int age) { m_name = name; m_age = age; m_resume = NULL; setResume("aaaa"); } void setResume(char *p) { if (m_resume != NULL) { delete m_resume; } m_resume = new char[strlen(p) + 1]; strcpy(m_resume, p); } virtual Person* clone() { CPlusPlusProgrammer *tmp = new CPlusPlusProgrammer; *tmp = *this; // 浅拷贝 (深拷贝需要考虑开辟空间的问题) 使用默认拷贝构造函数(值传递) return tmp; } virtual void printT() { cout << "m_name"<<m_name << " m_age" << m_age << "m_resume:" << m_resume << endl; } protected: private: }; int main() { Person *c1 = new CPlusPlusProgrammer("皇帝",20); c1->printT(); Person *c2 = c1->clone(); c2->printT(); system("pause"); return 0; }