C++设计模式 单例模式&工厂模式

目录

单例模式

懒汉式

饿汉式

工厂模式

简单工厂 

工厂方法

抽象工厂


设计模式为先辈总结的经验性结构,具有良好的代码复用性。。。

单例模式

单例模式属于创建型模式,有三种要点:

  1. 当前类最多只能创建一个实例。
  2. 它必须 自己创建这个实例,不能让调用者创建。
  3. 它必须自己向整个系统提供全局访问点访问这个实例。

单例模式的优点:

  1. 提供了严格的对唯一实例的创建、访问和销毁,安全性高。
  2. 单例模式的实现可以节省系统资源。 
单例模式-懒汉式

懒汉式:现用现创建,用创建的时间节省其他不需要它时候的空间。

写法一: 

class CSingleton {
private:
	CSingleton() {}
	CSingleton(const CSingleton&) = delete; //ban掉拷贝防止创建第二个单例。
	static CSingleton* p_sin; //与get函数同步采用静态
	~CSingleton() {} //析构私有,防止随意删除

	static class delsingleton { //最后的保底手段,定义一个类内类利用其析构在生命周期结束时自动回收单例。
	public:
		~delsingleton() {
			if (p_sin) {
				delete p_sin;
				p_sin = nullptr;
			}
		}
	} delsin;
public:
	static CSingleton* GetSingleton() { //为了保证调用时对象存在,采用静态
		if (!p_sin) { //空指针则调用构造
			p_sin = new CSingleton();
		}
		return p_sin;
	}

	static void DeleteSingleton(CSingleton*& pnow) { //删除也要 类内自己删除,不能让其直接调用析构。
		if (p_sin) {
			delete p_sin;
			p_sin = nullptr;
			pnow = nullptr;
		}
	}
};

CSingleton* CSingleton::p_sin = nullptr; //静态初始化
CSingleton::delsingleton CSingleton::delsin;

  遗留问题:在单线程模式下可以保证功能,多线程下仍有可能创建多个对象。需采用线程同步。

写法二:

class CSingleton {
private:
	CSingleton() {}
	CSingleton(const CSingleton&) = delete;
	~CSingleton() {}

public:
	static CSingleton* GetSingleton() {
		static CSingleton sin; //定义为静态,保证全局只创建一次,并且伴随程序结束自动回收。
		return &sin;
	}
};

 写法二不存在和写法一一样的遗留问题,由系统保证只会创建一个。

 对比:写法一虽然繁琐,但是可以做到随时删除,节省空间。写法二简洁,但删除相对死板。

单例模式-饿汉式

饿汉式:在程序运行前就将单例模式准备好。

class CSingleton {
private:
	CSingleton() {}
	CSingleton(const CSingleton&) = delete;
	~CSingleton() {}
	static CSingleton sin; // 直接在程序运行开始定义好,随时使用,由系统自动回收。
public:
	static CSingleton* GetSingleton() {
		return &sin;
	}
};
CSingleton CSingleton::sin;

缺陷:发生在跨文件使用时的一种问题,有概率在单例模式被创建好前就由其他文件使用这个单例,导致不能正确获取单例。 

例如:有四个文件A.h A.cpp B.cpp C.cpp,在A.h中定义单例模式,在C中初始化静态变量sin而在A、B、C中都使用单例模式创造变量。在生成顺序为A.cpp B.cpp C.cpp的情况下,A、B中的单例将不会有正确的值。

工厂模式

工厂模式-简单工厂 
class CEngine {
public:
	virtual void work() = 0;
};

class CEngine2L : public CEngine {
public:
	void work() {
		cout << "自然吸气 嗡嗡嗡\n";
	}
};

class CEngine2T : public CEngine {
public:
	void work() {
		cout << "涡轮增压 嗡嗡嗡\n";
	}
};

class CFactory {
public:
	CEngine* CreateEngine(const string& type) {
		if (type == "2.0L") {
			return new CEngine2L;
		}
		else if (type == "2.0T") {
			return new CEngine2T;
		}
		return nullptr;
	}
};

class CCar {
public:
	CEngine* p_eng;
	CCar(const string& type) {
		if (type == "2.0L") {
			p_eng = new CEngine2L;
		}
		else if (type == "2.0T") {
			p_eng = new CEngine2T;
		}
		else p_eng = nullptr;
	}
	//为何要引入简单工厂 ?解决 耦合 的问题。
	CCar(CFactory* pfac, const string& type)
		:p_eng(pfac ? pfac->CreateEngine(type) : nullptr) {

	}
	~CCar() {
		if (p_eng) {
			delete p_eng;
			p_eng = nullptr;
		}
	}
public:
	void drive() {
		if (p_eng) {
			p_eng->work();
			cout << "小汽车 呜呜开\n";
		}
	}
};
工厂模式-工厂方法

将工厂类内的创造函数定义为虚函数,并为每个零件定义子类继承工厂类。

class CFactoryEngine {
public:
	virtual CEngine* CreateEngine() = 0; //在这里使用虚函数
};

class CFac2L :public CFactoryEngine { //定义子类
public:
	CEngine* CreateEngine() {
		return new CEngine2L;
	}
};

class CFac2T :public CFactoryEngine {
public:
	CEngine* CreateEngine() {
		return new CEngine2T;
	}
};

使用时直接传入子类指针进行赋值。

CCar(CFactoryEngine* pfac) :p_eng(pfac ? pfac->CreateEngine() : nullptr) {}
CFac2L fac2L;
CFac2T fac2T;
CCar car(&fac2L);
car.drive();

好处:解决耦合,对修改关闭,对扩展开放,增加新零件时只需要继续扩展子类,而无需对工厂类内的代码进行更正。

工厂模式-抽象工厂

抽象工厂解决了工厂模式中类过多的问题,将产品合并形成合并的子类并进行创建,但实际应用中还需要考虑应用场景选择合适的工厂种类。

class CEngine {
public:
	virtual void work() = 0;
};

class CEngine2L : public CEngine {
public:
	void work() {
		cout << "自然吸气 嗡嗡嗡\n";
	}
};

class CEngine2T : public CEngine {
public:
	void work() {
		cout << "涡轮增压 嗡嗡嗡\n";
	}
};

class CGearBox {
public:
	virtual void work() = 0;
};

class CGearBoxManual :public CGearBox {
public:
	void work() {
		cout << "手动挡变速箱工作ing\n";
	}
};

class CGearBoxAuto :public CGearBox {
public:
	void work() {
		cout << "自动挡变速箱工作ing\n";
	}
};

class CFactory { //引入总体工厂
public:
	virtual CEngine* CreateEngine() = 0;
	virtual CGearBox* CreateGearBox() = 0;
};

class CFac2TManual :public CFactory { //总体工厂的子类为所需要的产品型号的合并类型
public:
	CEngine* CreateEngine() {
		return new CEngine2T;
	}
	CGearBox* CreateGearBox() {
		return new CGearBoxManual;
	}
};
class CCar {
public:
	CEngine* p_eng;
	CGearBox* p_gear;
	//引入抽象工厂
	CCar(CFactory* pfac) :
		p_eng(pfac ? pfac->CreateEngine() : nullptr),
		p_gear(pfac ? pfac->CreateGearBox() : nullptr) {
	}
	~CCar() {
		if (p_eng) {
			delete p_eng;
			p_eng = nullptr;
		}
		if (p_gear) {
			delete p_gear;
			p_gear = nullptr;
		}
	}
public:
	void drive() {
		if (p_eng && p_gear) {
			p_eng->work();
			p_gear->work();
			cout << "小汽车 呜呜开\n";
		}
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值