设计模式1—创建型模式

模式
         在一定环境中解决某一问题的方案,包括三个基本元素--问题,解决方案和环境。
         大白话:在一定环境下,用固定套路解决问题。
设计模式(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:
#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;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/497174.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++学习之路 | PTA乙级—— 1021 个位数统计 (15分)(精简)

1021 个位数统计 (15分) 给定一个 k 位整数 Nd ​k−1 ​​ 10 ​k−1 ​​ ⋯d ​1 ​​ 10 ​1 ​​ d ​0 ​​ (0≤d ​i ​​ ≤9, i0,⋯,k−1, d ​k−1 ​​ >0)&#xff0c;请编写程序统计每种不同的个位数字出现的次数。例如&#xff1a;给定 N100311&#xff0c;…

Collapse Hierarchy(折叠继承体系)

超类和子类之间无太大区别 重构&#xff1a;将它们合为一体

65% 的钱被头部玩家拿走,人工智能要进入下半场?

来源&#xff1a;IT桔子概要&#xff1a;2017年&#xff0c;自动驾驶、医疗影像、AI教育成为焦点&#xff1b;一多半AI风险投资被第一梯队选手收入囊中&#xff0c;并快速成长为独角兽。2017年&#xff0c;自动驾驶、医疗影像、AI教育成为焦点&#xff1b;一多半AI风险投资被第…

转:用ASP.NET创建网络相册

用ASP.NET创建网络相册 在现在的数码时代&#xff0c;我们会经常拍摄一些相片以供留念&#xff0c;而随着数码照片的增多&#xff0c;往往需要很好地管理这些照片&#xff0c;以便更好地查阅留念。现在网上有不少的电子相册&#xff0c;都能很好的实现这些功能&#xff0c;那我…

设计模式2—结构型模式

结构型模式用来处理类或者对象的组合&#xff0c;主要包含以下7种设计模式&#xff1a;1. 代理模式&#xff08;Proxy Pattern&#xff09;就是为其他对象提供一种代理以控制对这个对象的访问。2. 装饰者模式&#xff08;Decorator Pattern&#xff09;动态的给一个对象添加一些…

C++学习之路 | PTA乙级—— 1022 D进制的A+B (20分)(精简)

1022 D进制的AB (20分) 输入两个非负 10 进制整数 A 和 B (≤2 ​30 ​​ −1)&#xff0c;输出 AB 的 D (1<D≤10)进制数。 输入格式&#xff1a; 输入在一行中依次给出 3 个整数 A、B 和 D。 输出格式&#xff1a; 输出 AB 的 D 进制数。 输入样例&#xff1a; 123 45…

Form Template Method(塑造模板函数)

有一些子类&#xff0c;其中相应的某些函数以相同顺序执行类似的操作&#xff0c;但各个操作的细节有不同 重构&#xff1a;将这些操作分别放进独立函数中&#xff0c;并保持它们都有相同的签名&#xff0c;然后将原函数上移至超类

自动驾驶第一案结果敲定,谷歌无人驾驶和Uber达成2.5亿美元和解协议

来源&#xff1a;36氪概要&#xff1a;Uber 与谷歌无人驾驶部门 Waymo 的法律纠纷以庭外和解的方式告一段落。Uber 与谷歌无人驾驶部门 Waymo 的法律纠纷以庭外和解的方式告一段落。上周五 &#xff0c;Uber 表示&#xff0c;公司已经和 AlphabetInc 旗下的无人驾驶汽车公司 Wa…

FastReport v3.2.5在BDS2006中的安装方法

FastReport v3.2.5在BDS2006中的安装方法 // Windows XP Pro SP2 Delphi2006 Update 1 TeeChart pro v7.06 // 安装前请删除老版本的FastReport控件。 1. "Tools|Options|Environmet Options|Delphi Options|Library - Win32"中的"Directories"标签面…

C++学习之路 | PTA乙级—— 1023 组个最小数 (20分)(精简)

1023 组个最小数 (20分) 给定数字 0-9 各若干个。你可以以任意顺序排列这些数字&#xff0c;但必须全部使用。目标是使得最后得到的数尽可能小&#xff08;注意 0 不能做首位&#xff09;。例如&#xff1a;给定两个 0&#xff0c;两个 1&#xff0c;三个 5&#xff0c;一个 8…

物联网将在2018年实现大规模发展:以下是IBM的4大预测

来源&#xff1a;forbes物联网智库 编译概要&#xff1a;随着连接设备的数量达到110亿台&#xff08;不包括电脑和手机的连接量&#xff09;&#xff0c;很显然&#xff0c;在2018年&#xff0c;物联网将继续成为热点话题。随着连接设备的数量达到110亿台&#xff08;不包括电脑…

佛祖说出的爱情箴言

一、石头问&#xff1a;我究竟该找个我爱的人做我的妻子呢&#xff1f;还是该找个爱我的人做我的妻子呢&#xff1f;佛笑了笑&#xff1a;这个问题的答案其实就在你自己的心底。这些年来&#xff0c;能让你爱得死去活来&#xff0c;能让你感觉得到生活充实&#xff0c;能让你挺…

Replace Inheritance with Delegation(以委托取代继承)

某个子类只使用超类接口中的一部分&#xff0c;或是根本不需要继承而来的数据 重构&#xff1a;在子类中新建一个字段用来保存超类&#xff0c;调整子类函数&#xff0c;令它改而委托超类&#xff0c;然后去掉两者的继承关系

设计模式3—行为型模式

行为型模式用来对类或对象怎样交互和怎样分配职责进行描述&#xff0c;主要包含以下11种设计模式&#xff1a; 模板方法模式&#xff08;Template Method Pattern&#xff09; 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 命令模式&#xff08;Command…

javax.servlet.http.HttpServletRequest接口(HTTP版本)

< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd> HttpServletRequest类主要处理&#xff1a;1.读取和写入HTTP头标2.取得和设置cookies3.取得路径信息4.标识HTTP会话。HttpServletRequest接口中的方法 String getAuthType() …

C++学习之路 | PTA(天梯赛)—— L3-003 社交集群 (30分) (带注释) (并查集) (精简)

L3-003 社交集群 (30分) 当你在社交网络平台注册时&#xff0c;一般总是被要求填写你的个人兴趣爱好&#xff0c;以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。 输入格式&#xff1a; 输入在第一行给出…

国家重点研发计划高新领域 “智能机器人、网络协同制造和智能工厂”重点专项2018年度项目申报指南建议

来源&#xff1a;机器人创新生态概要&#xff1a; 针对我国网络协同制造和智能工厂发展模式创新不足、技术能力尚未形成、融合新生态发展不足、核心技术/软件支撑能力薄弱等问题。征求意见时间为2018年2月8日至2018年2月22日。电子邮箱&#xff1a;重点专项名称邮箱地址智能机器…

Replace Delegation with Inheritance(以继承取代委托)

两个类之间使用委托关系&#xff0c;并经常为整个接口编写许多极简单的委托函数 重构&#xff1a;让委托类继承受托类

C++学习之路 | PTA(天梯赛)—— L2-024 部落 (25分)(带注释)(并查集)(精简)

L2-024 部落 (25分) 在一个社区里&#xff0c;每个人都有自己的小圈子&#xff0c;还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里&#xff0c;于是要请你统计一下&#xff0c;在一个给定社区中&#xff0c;到底有多少个互不相交的部落&#xff1f;并且检…

人造神经元计算速度超过人脑

来源&#xff1a;《科学进展》概要&#xff1a;一种以神经元为模型的超导计算芯片&#xff0c;能比人脑更高效快速地加工处理信息。一种以神经元为模型的超导计算芯片&#xff0c;能比人脑更高效快速地加工处理信息。近日刊登于《科学进展》的新成果&#xff0c;或许将成为科学…