C++11 设计模式6. 建造者模式,也叫做生成器模式

2024-04-30 12:20

本文主要是介绍C++11 设计模式6. 建造者模式,也叫做生成器模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一 什么是建造者模式?

// 小木公司对于SQL有配置,因此要输入sql url,然后输入 sql username,然后是 sql ps
//因此小木就想到了使用 SystemConfig这个类来完成上述的三个初始化

//5.1号小木公司加入了redis的缓存机制,redis也有 url,username,password,三个字符串

//10.1之后,小木公司加入了kafka机制,让log都存储到kafka中,kafka也有url,username,password,三个字符串

//说不定过年后,还有加上其他配置项。这时候小木意识到问题的严重性了,
//每次改动都一堆参数,且容易出现问题

// 小木公司对于SQL有配置,因此要输入sql url,然后输入 sql username,然后是 sql ps
//因此小木就想到了使用 SystemConfig这个类来完成上述的三个初始化//5.1号小木公司加入了redis的缓存机制,redis也有 url,username,password,三个字符串//10.1之后,小木公司加入了kafka机制,让log都存储到kafka中,kafka也有url,username,password,三个字符串//说不定过年后,还有加上其他配置项。这时候小木意识到问题的严重性了,
//每次改动都一堆参数,且容易出现问题
#include <iostream>
#include <string>
using namespace std;class SystemConfig {public:SystemConfig(string sqlurl,string sqlusername,string sqlpassword,string redisurl, string redisusername, string redispassword,string kafkaurl, string kafkausername, string kafkapassword): MySQL_URL(sqlurl), MySQL_username(sqlusername), MySQL_password(sqlpassword),REDIS_URL(redisurl), REDIS_username(redisusername), REDIS_password(redispassword),KAFKA_URL(kafkaurl), KAFKA_username(kafkausername), KAFKA_password(kafkapassword){}void printfSysConfig() {cout << "MySQL_URL = " << MySQL_URL<< "   MySQL_username = " << MySQL_username<< "   MySQL_password = " << MySQL_password<< "   REDIS_URL = " << REDIS_URL<< "   REDIS_username = " << REDIS_username<< "   REDIS_password = " << REDIS_password<< "   KAFKA_URL = " << KAFKA_URL<< "   KAFKA_username = " << KAFKA_username<< "   KAFKA_password = " << KAFKA_password<< endl;}
private:string MySQL_URL;string MySQL_username;string MySQL_password;//5.1之后string REDIS_URL;string REDIS_username;string REDIS_password;//10.1之后string KAFKA_URL;string KAFKA_username;string KAFKA_password;
};//想到的第一解决方案是:我们将这些属性都弄成函数,class SystemConfig1 {public:SystemConfig1() {}void setMySQLConfig(string sqlurl, string sqlusername, string sqlpassword) {this->MySQL_URL = sqlurl;this->MySQL_username = sqlusername;this->MySQL_password = sqlpassword;}void setRedisConfig(string redisurl, string redisusername, string redispassword) {this->REDIS_URL = redisurl;this->REDIS_username = redisusername;this->REDIS_password = redispassword;}void setKAFKAConfig(string kafkaurl, string kafkausername, string kafkapassword) {this->KAFKA_URL = kafkaurl;this->KAFKA_username = kafkausername;this->KAFKA_password = kafkapassword;}void printfSysConfig() {cout << "MySQL_URL = " << MySQL_URL<< "   MySQL_username = " << MySQL_username<< "   MySQL_password = " << MySQL_password<< "   REDIS_URL = " << REDIS_URL<< "   REDIS_username = " << REDIS_username<< "   REDIS_password = " << REDIS_password<< "   KAFKA_URL = " << KAFKA_URL<< "   KAFKA_username = " << KAFKA_username<< "   KAFKA_password = " << KAFKA_password<< endl;}
private:string MySQL_URL;string MySQL_username;string MySQL_password;//5.1之后string REDIS_URL;string REDIS_username;string REDIS_password;//10.1之后string KAFKA_URL;string KAFKA_username;string KAFKA_password;
};//构造者模式
//创建一个sustemconfig的build类,创建systemconfig的过程全都交给这个systemconfig类来实现class SystemConfig2 {
public:SystemConfig2() {}void printfSysConfig() {cout << "MySQL_URL = " << MySQL_URL<< "   MySQL_username = " << MySQL_username<< "   MySQL_password = " << MySQL_password<< "   REDIS_URL = " << REDIS_URL<< "   REDIS_username = " << REDIS_username<< "   REDIS_password = " << REDIS_password<< "   KAFKA_URL = " << KAFKA_URL<< "   KAFKA_username = " << KAFKA_username<< "   KAFKA_password = " << KAFKA_password<< endl;}
public:string MySQL_URL;string MySQL_username;string MySQL_password;//5.1之后string REDIS_URL;string REDIS_username;string REDIS_password;//10.1之后string KAFKA_URL;string KAFKA_username;string KAFKA_password;
};class SystemConfig2Build {public:SystemConfig2Build() {}SystemConfig2 & getSystemConfig() {return systemconfig;}void setMySQLConfig(string sqlurl, string sqlusername, string sqlpassword) {systemconfig.MySQL_URL = sqlurl;systemconfig.MySQL_username = sqlusername;systemconfig.MySQL_password = sqlpassword;}void setRedisConfig(string redisurl, string redisusername, string redispassword) {systemconfig.REDIS_URL = redisurl;systemconfig.REDIS_username = redisusername;systemconfig.REDIS_password = redispassword;}void setKAFKAConfig(string kafkaurl, string kafkausername, string kafkapassword) {systemconfig.KAFKA_URL = kafkaurl;systemconfig.KAFKA_username = kafkausername;systemconfig.KAFKA_password = kafkapassword;}private:SystemConfig2  systemconfig;
};class CompanyA {
public:virtual SystemConfig2 & buildSystemConfig() {scbuild2.setMySQLConfig("11a", "22a", "33a");scbuild2.setRedisConfig("44a", "55a", "66a");scbuild2.setKAFKAConfig("77a", "88a", "99a");return scbuild2.getSystemConfig();}private:SystemConfig2Build scbuild2;
};class CompanyB {
public:SystemConfig2 & buildSystemConfig() {scbuild2.setMySQLConfig("11B", "22B", "33B");scbuild2.setRedisConfig("44B", "55B", "66B");scbuild2.setKAFKAConfig("77B", "88B", "99B");return scbuild2.getSystemConfig();}private:SystemConfig2Build scbuild2;
};class CompanyDiect {
public:virtual SystemConfig2 & buildSystemConfig() = 0;virtual ~CompanyDiect() {//注意父类的 析构函数 要写成 virtual形式的。}
private:SystemConfig2Build scbuild2;
};//c公司
class CompanyDiectc:public CompanyDiect {
public:virtual SystemConfig2 & buildSystemConfig() {scbuild2.setMySQLConfig("11c", "22c", "33c");scbuild2.setRedisConfig("44c", "55c", "66c");scbuild2.setKAFKAConfig("77c", "88c", "99c");return scbuild2.getSystemConfig();}private:SystemConfig2Build scbuild2;
};class CompanyDiectd :public CompanyDiect {
public:virtual SystemConfig2 & buildSystemConfig() {scbuild2.setMySQLConfig("11d", "22d", "33d");scbuild2.setRedisConfig("44d", "55d", "66d");scbuild2.setKAFKAConfig("77d", "88d", "99d");return scbuild2.getSystemConfig();}private:SystemConfig2Build scbuild2;
};int main()
{_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口std::cout << "Hello World!\n";SystemConfig sc = SystemConfig("aa","bb","cc","dd","ee","ff","11","22","33");sc.printfSysConfig();//首先想到的fix方案,但是有个问题,就是开出来了public接口,让user可以调用,这不怎么好。//也就是说破坏了原有的systemConfig的封装性,让user可以有机会再次改动。虽然不得不这么干。SystemConfig1 sc1 = SystemConfig1();sc1.setMySQLConfig("SQL11", "SQL22", "SQL33");sc1.setRedisConfig("redis1", "redis2", "redis3");sc1.setKAFKAConfig("kafka1", "kafka2", "kafka3");sc1.printfSysConfig();//构造者模式的调用SystemConfig2Build scbuild2;scbuild2.setMySQLConfig("11", "22", "33");scbuild2.setRedisConfig("44", "55", "66");scbuild2.setKAFKAConfig("77", "88", "99");SystemConfig2 sc2 = scbuild2.getSystemConfig();sc2.printfSysConfig();//我们看到上述构造者模式的调用,每次都要传递参数进入,实际开发中,我们可能对于A,B公司的配置基本是不变的,也就是说,我们需要一些预选项CompanyA ca;SystemConfig2 sca = ca.buildSystemConfig();sca.printfSysConfig();//B公司CompanyB cB;SystemConfig2 scB = cB.buildSystemConfig();scB.printfSysConfig();//我们看代码知道 CompanyA 和 CompanyB 的代码是完全一样的,因此可以抽取成父类,这样CompanyDiect * comabs;comabs = new CompanyDiectc(); //多态完成SystemConfig2 scconn = comabs->buildSystemConfig();scconn.printfSysConfig();delete comabs;}

        建造者模式(也被成为⽣成器模式),是⼀种创建型设计模式,软件开发过程中有的时候需要创建很复杂的对象,⽽建造者模式的主要思想是将对象的构建过程分为多个步骤,并为每个步骤定义⼀个抽象的接⼝。具体的构建过程由实现了这些接⼝的具体建造者类来完成。同时有⼀个指导者类负责协调建造者的⼯作,按照⼀定的顺序或逻辑来执⾏构建步骤,最终⽣成产品。
        举个例⼦,假如我们要创建⼀个计算机对象,计算机由很多组件组成,例如 CPU、内存、硬盘、显卡等每个组件可能有不同的型号、配置和制造,这个时候计算机就可以被视为⼀个复杂对象,构建过程相对复杂,⽽我们使⽤建造者模式将计算机的构建过程封装在⼀个具体的建造者类中,⽽指导者类则负责指导构建的步骤和顺序。每个具体的建造者类可以负责构建不同型号或配置的计算机,客户端代码可以通过选择不同的建造者来创建不同类型的计算机,这样就可以根据需要构建不同表示的复杂对象,更加灵活。

假设我们要创建一个计算机对象,普通的写法如下:

// 004构建者模式.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include <string>
using namespace std;//cpu 
class CPU {
public:CPU(string cpuname) :_cpuname(cpuname) {cout << "CPU 构造方法被调用 _cpuname = " << _cpuname << endl;}
public:string _cpuname;};class Memory {
public:Memory(string memname) :_memname(memname) {cout << "Memory 构造方法被调用 _memname = " << memname << endl;}
public:string _memname;
};class Harddisk {
public:Harddisk(string diskname) :_diskname(diskname) {cout << "Harddisk 构造方法被调用 diskname = " << diskname << endl;}
public:string _diskname;
};class GraphicsCard {
public:GraphicsCard(string gcname) :_gcname(gcname) {cout << "GraphicsCard 构造方法被调用 _gcname = " << _gcname << endl;}
public:string _gcname;
};//如果是普通的写法
//假如我们要创建⼀个计算机对象,计算机由很多组件组成,
//例如 CPU、内存、硬盘、显卡等。
//每个组件可能有不同的型号、配置和制造,
//这个时候计算机就可以被视为⼀个复杂对象
class Computer {
public:Computer(CPU *cpu, Memory *mem, Harddisk *hdisk, GraphicsCard *gc):_cpu(cpu),_mem(mem),_hdisk(hdisk),_gc(gc) {cout << "Computer 构造方法被调用" << endl;}~Computer() {cout << "Computer 析构方法被调用" << endl;}void printfCom() {cout << "cpu = " << this->_cpu->_cpuname<< "   mem = " << this->_mem->_memname<< "   hdisk = " << this->_hdisk->_diskname<< "   gc = " << this->_gc->_gcname<<endl;}
protected:CPU *_cpu;Memory *_mem;Harddisk *_hdisk;GraphicsCard *_gc;
};int main()
{std::cout << "Hello World!\n";CPU cpu("intelcpu");Memory mem("sanxingmem");Harddisk disk("xindisk");GraphicsCard gc("huaweixianka");Computer comA(&cpu,&mem,&disk,&gc);comA.printfCom();//这里有个问题,如果我们创建的cpmputer比较多,又有不同的型号,那么很容易写错。//创建者模型就是解决这个问题
}

和继承的写法结合在一起

// 004构建者模式正确的写法.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include <string>
using namespace std;//使用构造者模式创建
class CPUBase {
public:CPUBase(string cpuname) :_cpuname(cpuname) {cout << "CPUBase 构造方法被调用 _cpuname = " << _cpuname << endl;}public:string _cpuname;
};class HuaweiCpu : public CPUBase {
public:HuaweiCpu(string cpuname) :CPUBase(cpuname) {cout << "HuaweiCpu 构造方法被调用 _cpuname = " << _cpuname << endl;}
};
class xiaomiCpu : public CPUBase {
public:xiaomiCpu(string cpuname) :CPUBase(cpuname) {cout << "xiaomiCpu 构造方法被调用 _cpuname = " << _cpuname << endl;}
};
class lianxiangCpu : public CPUBase {
public:lianxiangCpu(string cpuname) :CPUBase(cpuname) {cout << "lianxiangCpu 构造方法被调用 _cpuname = " << _cpuname << endl;}
};class MemoryBase {
public:MemoryBase(string memname) :_memname(memname) {cout << "MemoryBase 构造方法被调用 _memname = " << memname << endl;}
public:string _memname;
};
class huaweiMemory :public MemoryBase {
public:huaweiMemory(string memname) :MemoryBase(memname) {cout << "huaweiMemory 构造方法被调用 _memname = " << memname << endl;}
};
class xiaomiMemory :public MemoryBase {
public:xiaomiMemory(string memname) :MemoryBase(memname) {cout << "xiaomiMemory 构造方法被调用 _memname = " << memname << endl;}
};
class lianxiangMemory :public MemoryBase {
public:lianxiangMemory(string memname) :MemoryBase(memname) {cout << "lianxiangMemory 构造方法被调用 _memname = " << memname << endl;}
};class HarddiskBase {
public:HarddiskBase(string diskname) :_diskname(diskname) {cout << "HarddiskBase 构造方法被调用 diskname = " << diskname << endl;}
public:string _diskname;
};
class huaweiHarddisk :public HarddiskBase {
public:huaweiHarddisk(string diskname) :HarddiskBase(diskname) {cout << "huaweiHarddisk 构造方法被调用 _diskname = " << diskname << endl;}
};
class xiaomiHarddisk :public HarddiskBase {
public:xiaomiHarddisk(string diskname) :HarddiskBase(diskname) {cout << "xiaomiHarddisk 构造方法被调用 diskname = " << diskname << endl;}
};
class lianxiangHarddisk :public HarddiskBase {
public:lianxiangHarddisk(string diskname) :HarddiskBase(diskname) {cout << "lianxiangHarddisk 构造方法被调用 diskname = " << diskname << endl;}
};class GraphicsCardBase {
public:GraphicsCardBase(string gcname) :_gcname(gcname) {cout << "GraphicsCardBase 构造方法被调用 _gcname = " << _gcname << endl;}
public:string _gcname;
};
class huaweiGraphicsCard :public GraphicsCardBase {
public:huaweiGraphicsCard(string gcname) :GraphicsCardBase(gcname) {cout << "huaweiHarddisk 构造方法被调用 gcname = " << gcname << endl;}
};
class xiaomiGraphicsCard :public GraphicsCardBase {
public:xiaomiGraphicsCard(string gcname) :GraphicsCardBase(gcname) {cout << "xiaomiGraphicsCard 构造方法被调用 gcname = " << gcname << endl;}
};
class lianxiangGraphicsCard :public GraphicsCardBase {
public:lianxiangGraphicsCard(string gcname) :GraphicsCardBase(gcname) {cout << "lianxiangGraphicsCard 构造方法被调用 gcname = " << gcname << endl;}
};class ComputerBase {public:virtual ~ComputerBase() {};void printComputerBase() {cout << "_cpuBase = " << this->_cpuBase<< "   _memBase = " << this->_memBase<< "   _hdiskBase = " << this->_hdiskBase<< "   _gcBase = " << this->_gcBase<< endl;}// 一般需要给私有的成员属性提供读写接口CPUBase* GetCPUBase() {return this->_cpuBase;}void SetCPUBase(CPUBase* cpubase) {this->_cpuBase = cpubase;}MemoryBase* GetMemoryBase() {return this->_memBase;}void SetMemoryBase(MemoryBase* membase) {this->_memBase = membase;}HarddiskBase* GetHarddiskBase() {return this->_hdiskBase;}void SetHarddiskBase(HarddiskBase* hdiskBase) {this->_hdiskBase = hdiskBase;}GraphicsCardBase* GetGraphicsCardBase() {return this->_gcBase;}void SetGraphicsCardBase(GraphicsCardBase* gcBase) {this->_gcBase = gcBase;}protected:CPUBase *_cpuBase;MemoryBase *_memBase;HarddiskBase *_hdiskBase;GraphicsCardBase *_gcBase;
};class huaweiComputer :public ComputerBase {};class lianxiangComputer :public ComputerBase {};class xiaomiComputer :public ComputerBase {};//构建器父类
class ComputerBaseBuilder {
public:virtual ~ComputerBaseBuilder() {};virtual void loadCPU(string cpubase) = 0;virtual void loadMem(string membase) = 0;virtual void loaddisk(string diskbase) = 0;virtual void loadGraphicsCard(string graphicsCardbase) = 0;ComputerBase * getCompBase() {return m_compBase;}
protected:ComputerBase *m_compBase;
};class huaweiComputerBuild :public ComputerBaseBuilder {
public:huaweiComputerBuild() {m_compBase = new huaweiComputer();}virtual void loadCPU(string strmodelno) {CPUBase *cpu = nullptr;if (strmodelno == "001") {cpu = new HuaweiCpu("huaweicpu");}if (strmodelno == "002") {cpu = new xiaomiCpu("xiaomicpu");}if (strmodelno == "003") {cpu = new lianxiangCpu("lianxiangcpu");}cout << "huaweiComputerBuild loadCPU" << endl;m_compBase->SetCPUBase(cpu);}virtual void loadMem(string strmodelno) {MemoryBase *memBase = nullptr;if (strmodelno == "001") {memBase = new huaweiMemory("huaweimemory");}if (strmodelno == "002") {memBase = new xiaomiMemory("xiaomimemory");}if (strmodelno == "003") {memBase = new lianxiangMemory("lianxiangmemory");}cout << "huaweiComputerBuild loadmemory" << endl;m_compBase->SetMemoryBase(memBase);}virtual void loaddisk(string strmodelno) {HarddiskBase *hdiskBase = nullptr;if (strmodelno == "001") {hdiskBase = new huaweiHarddisk("huaweidisk");}if (strmodelno == "002") {hdiskBase = new xiaomiHarddisk("xiaomidisk");}if (strmodelno == "003") {hdiskBase = new lianxiangHarddisk("lianxiangdisk");}cout << "huaweiComputerBuild loaddisk" << endl;m_compBase->SetHarddiskBase(hdiskBase);}virtual void loadGraphicsCard(string strmodelno) {GraphicsCardBase *_gcBase = nullptr;if (strmodelno == "001") {_gcBase = new huaweiGraphicsCard("huaweigc");}if (strmodelno == "002") {_gcBase = new xiaomiGraphicsCard("huaweigc");}if (strmodelno == "003") {_gcBase = new lianxiangGraphicsCard("huaweigc");}cout << "huaweiComputerBuild loadgcbase" << endl;m_compBase->SetGraphicsCardBase(_gcBase);}~huaweiComputerBuild() {}
};class lianxiangComputerBuild :public ComputerBaseBuilder {
public:lianxiangComputerBuild() {m_compBase = new lianxiangComputer();}virtual void loadCPU(string strmodelno) {CPUBase *cpu = nullptr;if (strmodelno == "001") {cpu = new HuaweiCpu("huaweicpu");}if (strmodelno == "002") {cpu = new xiaomiCpu("xiaomicpu");}if (strmodelno == "003") {cpu = new lianxiangCpu("lianxiangcpu");}cout << "huaweiComputerBuild loadCPU" << endl;m_compBase->SetCPUBase(cpu);}virtual void loadMem(string strmodelno) {MemoryBase *memBase = nullptr;if (strmodelno == "001") {memBase = new huaweiMemory("huaweimemory");}if (strmodelno == "002") {memBase = new xiaomiMemory("xiaomimemory");}if (strmodelno == "003") {memBase = new lianxiangMemory("lianxiangmemory");}cout << "huaweiComputerBuild loadmemory" << endl;m_compBase->SetMemoryBase(memBase);}virtual void loaddisk(string strmodelno) {HarddiskBase *hdiskBase = nullptr;if (strmodelno == "001") {hdiskBase = new huaweiHarddisk("huaweidisk");}if (strmodelno == "002") {hdiskBase = new xiaomiHarddisk("xiaomidisk");}if (strmodelno == "003") {hdiskBase = new lianxiangHarddisk("lianxiangdisk");}cout << "huaweiComputerBuild loaddisk" << endl;m_compBase->SetHarddiskBase(hdiskBase);}virtual void loadGraphicsCard(string strmodelno) {GraphicsCardBase *_gcBase = nullptr;if (strmodelno == "001") {_gcBase = new huaweiGraphicsCard("huaweigc");}if (strmodelno == "002") {_gcBase = new xiaomiGraphicsCard("huaweigc");}if (strmodelno == "003") {_gcBase = new lianxiangGraphicsCard("huaweigc");}cout << "huaweiComputerBuild loadgcbase" << endl;m_compBase->SetGraphicsCardBase(_gcBase);}~lianxiangComputerBuild() {}
};class xiaomiComputerBuild :public ComputerBaseBuilder {
public:xiaomiComputerBuild() {m_compBase = new xiaomiComputer();}virtual void loadCPU(string strmodelno) {CPUBase *cpu = nullptr;if (strmodelno == "001") {cpu = new HuaweiCpu("huaweicpu");}if (strmodelno == "002") {cpu = new xiaomiCpu("xiaomicpu");}if (strmodelno == "003") {cpu = new lianxiangCpu("lianxiangcpu");}cout << "huaweiComputerBuild loadCPU" << endl;m_compBase->SetCPUBase(cpu);}virtual void loadMem(string strmodelno) {MemoryBase *memBase = nullptr;if (strmodelno == "001") {memBase = new huaweiMemory("huaweimemory");}if (strmodelno == "002") {memBase = new xiaomiMemory("xiaomimemory");}if (strmodelno == "003") {memBase = new lianxiangMemory("lianxiangmemory");}cout << "huaweiComputerBuild loadmemory" << endl;m_compBase->SetMemoryBase(memBase);}virtual void loaddisk(string strmodelno) {HarddiskBase *hdiskBase = nullptr;if (strmodelno == "001") {hdiskBase = new huaweiHarddisk("huaweidisk");}if (strmodelno == "002") {hdiskBase = new xiaomiHarddisk("xiaomidisk");}if (strmodelno == "003") {hdiskBase = new lianxiangHarddisk("lianxiangdisk");}cout << "huaweiComputerBuild loaddisk" << endl;m_compBase->SetHarddiskBase(hdiskBase);}virtual void loadGraphicsCard(string strmodelno) {GraphicsCardBase *_gcBase = nullptr;if (strmodelno == "001") {_gcBase = new huaweiGraphicsCard("huaweigc");}if (strmodelno == "002") {_gcBase = new xiaomiGraphicsCard("xiaomigc");}if (strmodelno == "003") {_gcBase = new lianxiangGraphicsCard("lianxianggc");}cout << "huaweiComputerBuild loadgcbase" << endl;m_compBase->SetGraphicsCardBase(_gcBase);}~xiaomiComputerBuild() {}
};//指挥者类
class ComputerDirector {public:ComputerDirector(ComputerBaseBuilder *computerBaseBuilder) {this->m_pComputerBaseBuilder = computerBaseBuilder;}//指定新的构建器void SetBuilder(ComputerBaseBuilder* ptmpBuilder){m_pComputerBaseBuilder = ptmpBuilder;}//原MonsterBuilder类中的Assemble成员函数ComputerBase *Construct(string strmodelno) //参数:模型编号,形如:“002001003001”等。每些位的组合都有一些特别的含义,这里不需要探究。{m_pComputerBaseBuilder->loadCPU(strmodelno.substr(0, 3));m_pComputerBaseBuilder->loadMem(strmodelno.substr(3, 3));m_pComputerBaseBuilder->loaddisk(strmodelno.substr(6, 3));m_pComputerBaseBuilder->loadGraphicsCard(strmodelno.substr(9, 3));return m_pComputerBaseBuilder->getCompBase();}private:ComputerBaseBuilder* m_pComputerBaseBuilder; //指向所有构建器类的父类
};int main()
{_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口xiaomiComputerBuild* xiaocomp = new xiaomiComputerBuild();ComputerDirector *cd = new ComputerDirector(xiaocomp);ComputerBase *combase = cd->Construct("001001001001");delete(combase->GetCPUBase());delete(combase->GetMemoryBase());delete(combase->GetHarddiskBase());delete(combase->GetGraphicsCardBase());combase->printComputerBase();delete combase;delete cd;delete xiaocomp;
}

这篇关于C++11 设计模式6. 建造者模式,也叫做生成器模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/948851

相关文章

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

C++的模板(八):子系统

平常所见的大部分模板代码,模板所传的参数类型,到了模板里面,或实例化为对象,或嵌入模板内部结构中,或在模板内又派生了子类。不管怎样,最终他们在模板内,直接或间接,都实例化成对象了。 但这不是唯一的用法。试想一下。如果在模板内限制调用参数类型的构造函数会发生什么?参数类的对象在模板内无法构造。他们只能从模板的成员函数传入。模板不保存这些对象或者只保存他们的指针。因为构造函数被分离,这些指针在模板外

C++工程编译链接错误汇总VisualStudio

目录 一些小的知识点 make工具 可以使用windows下的事件查看器崩溃的地方 dumpbin工具查看dll是32位还是64位的 _MSC_VER .cc 和.cpp 【VC++目录中的包含目录】 vs 【C/C++常规中的附加包含目录】——头文件所在目录如何怎么添加,添加了以后搜索头文件就会到这些个路径下搜索了 include<> 和 include"" WinMain 和

如何开启和关闭3GB模式

https://jingyan.baidu.com/article/4d58d5414dfc2f9dd4e9c082.html

C/C++的编译和链接过程

目录 从源文件生成可执行文件(书中第2章) 1.Preprocessing预处理——预处理器cpp 2.Compilation编译——编译器cll ps:vs中优化选项设置 3.Assembly汇编——汇编器as ps:vs中汇编输出文件设置 4.Linking链接——链接器ld 符号 模块,库 链接过程——链接器 链接过程 1.简单链接的例子 2.链接过程 3.地址和

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C++学习 贝蒂的主页:Betty’s blog 1. 泛型编程 首先让我们来思考一个问题,如何实现一个交换函数? void swap(int& x, int& y){int tmp = x;x = y;y = tmp;} 相信大家很快就能写出上面这段代码,但是如果要求这个交换函数支持字符型

十五.各设计模式总结与对比

1.各设计模式总结与对比 1.1.课程目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。 3、 了解各设计模式之间的关联,解决设计模式混淆的问题。 1.2.内容定位 1、 掌握设计模式的"道" ,而不只是"术" 2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。 3、 不要为了

十四、观察者模式与访问者模式详解

21.观察者模式 21.1.课程目标 1、 掌握观察者模式和访问者模式的应用场景。 2、 掌握观察者模式在具体业务场景中的应用。 3、 了解访问者模式的双分派。 4、 观察者模式和访问者模式的优、缺点。 21.2.内容定位 1、 有 Swing开发经验的人群更容易理解观察者模式。 2、 访问者模式被称为最复杂的设计模式。 21.3.观察者模式 观 察 者 模 式 ( Obser