从0到机器视觉工程师(五):C++设计模式

单例模式

单例设计模式(Singleton Pattern)是一种常用的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。

步骤

  • 将构造函数和析构函数设为私有成员函数
  • 创建一个静态单例指针
  • 通过一个接口来获取单例指针
cpp 复制代码
#include <iostream>
using namespace std;

class Signalton
{
public:
	static Signalton* ptr()
	{
		return m_ptr;
	}
	void Init(){};
	void Load(){};
	void Run(){};
private:
	Signalton(){};
	~Signalton(){};
private:
	static Signalton* m_ptr;
};
Signalton* Signalton::m_ptr = new Signalton();

//好处之一:直接使用不需要传入指针变量
void function1()
{
	Signalton* p = Signalton::ptr();
	p->Init();
	p->Load();
	p->Run();
}
int main()
{
	//错误
	//构造函数私有,不能构建对象
	//Signalton* p = new Signalton();

	//好处之一:只生成一个指针对象
	//p1和p2是同一个对象指针
	Signalton* p1 = Signalton::ptr();
	Signalton* p2 = Signalton::ptr();
	p1->Init();
	p1->Load();
	p1->Run();

	return 0;
}

监听者和观察者模式

**监听者模式(Listener Pattern)和观察者模式(Observer Pattern)**通常被用来实现对象之间的通知和响应机制。

观察者通常为一个,一般采用单例设计模式,通过观察者来监听事件的触发,告知监听者从而触发响应事件。当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。

cpp 复制代码
#include <iostream>
#include <map>
#include <vector>
#include <string>
using namespace std;

enum MESSAGE {
	EAT = 0x00000001,
	SLEEP = 0x00000002,
	SPORT = 0x00000004,
	PLAY = 0x00000008,
};
//监听者
class Listener
{
public:
	Listener() {};
	virtual ~Listener() {};
	virtual void RespondMessage(int message) = 0;  //响应处理事件
};

//观察者
class ListenterManager
{
public:
	using ml = map<int, vector<Listener*>>;
	static ListenterManager* ptr()
	{
		return m_ptr;
	}
	//注册事件
	void registerMessage(int message,Listener* listener)
	{
		//寻找是否有该事件
		auto iter = m_messageToListener.find(message);
		if (iter == m_messageToListener.end())  //若没有该事件
		{
			vector<Listener*> lister;
			lister.push_back(listener);
			m_messageToListener[message] = lister;
		}
		else //若存在该事件
		{
			iter->second.push_back(listener);
		}

	}
	//事件到来,通知监听者
	void nodify(int message)
	{
		auto iter = m_messageToListener.find(message);
		if (iter != m_messageToListener.end())
		{
			for (auto v : iter->second)
			{
				v->RespondMessage(message);
			}
		}
		else
		{
			cout << "no Listener has insterested this message" << endl;

		}
	}
private:
	ListenterManager() {};
	~ListenterManager() {};
private:
	static ListenterManager* m_ptr;
	map<int, vector<Listener*>> m_messageToListener;  //事件-监听者列表
};
ListenterManager* ListenterManager::m_ptr = new ListenterManager();

//监听者1
class Listener1 :public Listener
{
public:
	Listener1() {};
	void RespondMessage(int message)override
	{
		if (message == MESSAGE::EAT)
		{
			cout << "listener1" << endl;
		}
	}
};

//监听者2
class Listener2:public Listener
{
public:
	Listener2() {};
	void RespondMessage(int message)override
	{
		if (message == MESSAGE::PLAY)
		{
			cout << "listener2" << endl;
		}
	}
};

//监听者3
class Listener3 :public Listener
{
public:
	Listener3() {};
	void RespondMessage(int message)override
	{
		if (message == MESSAGE::SLEEP)
		{
			cout << "listener3" << endl;
		}
	}
};
int main()
{
	Listener1 listener1;
	Listener2 listener2;
	Listener3 listener3;

	ListenterManager::ptr()->registerMessage(MESSAGE::EAT, &listener1);
	ListenterManager::ptr()->registerMessage(MESSAGE::PLAY, &listener2);
	ListenterManager::ptr()->registerMessage(MESSAGE::SLEEP, &listener3);

	ListenterManager::ptr()->nodify(MESSAGE::SLEEP);
	return 0;
}

工厂模式

  • 简单工厂模式:通过一个工厂类来创建对象,客户端通过工厂类来获取对象。(一个工厂)
  • 工厂方法模式:定义一个用于创建对象的接口,由子类决定要实例化的类是哪一个。(多个工厂)
  • 抽象工厂模式:提供一个接口,用于创建一系列相关或相互依赖的对象。

简单工厂模式

通过一个工厂类来创建对象,客户端通过工厂类来获取对象,而不需要直接使用 new 关键字。这种模式的优点是代码更加简洁,但是它违反了开闭原则,因为每次添加新的产品时都需要修改工厂类。

cpp 复制代码
#include <iostream>
#include <map>
#include <vector>
#include <string>
using namespace std;

//简单工厂模式
//接口
class Shape
{
public:
	virtual void draw() = 0;
	virtual ~Shape() {};
};
//具体产品
class Circle :public Shape
{
public:
	void draw()override
	{
		cout << "draw a circle!" << endl;
	}
};
class Rectangle :public Shape
{
public:
	void draw()override
	{
		cout << "draw a rectangle!" << endl;
	}
};
class Triangle :public Shape
{
public:
	void draw()override
	{
		cout << "draw a triangle!" << endl;
	}
};
//工厂类
class ShapeFactory
{
public:
	Shape* getShape(const string& shapeType)
	{
		if (shapeType == "Circle")
		{
			return new Circle;
		}
		else if (shapeType == "Rectangle")
		{
			return new Rectangle;
		}
		else if (shapeType == "Triangle")
		{
			return new Triangle;
		}
		else
		{
			//...
		}
	}

};
int main()
{
	ShapeFactory* factory = new ShapeFactory;
	Shape* shape1 = factory->getShape("Circle");
	Shape* shape2 = factory->getShape("Rectangle");
	Shape* shape3 = factory->getShape("Triangle");
	shape1->draw();
	shape2->draw();
	shape3->draw();

	return 0;
}

工厂方法模式

工厂方法模式是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。

cpp 复制代码
#include <iostream>
#include <map>
#include <vector>
#include <string>
using namespace std;

//工厂方法模式
//接口
class Shape
{
public:
	virtual void draw() = 0;
	virtual ~Shape() {};
};
//具体产品
class Circle :public Shape
{
public:
	void draw()override
	{
		cout << "draw a circle!" << endl;
	}
};
class Rectangle :public Shape
{
public:
	void draw()override
	{
		cout << "draw a rectangle!" << endl;
	}
};
class Triangle :public Shape
{
public:
	void draw()override
	{
		cout << "draw a triangle!" << endl;
	}
};
//工厂类
class ShapeFactory
{
public:
	virtual Shape* getShape() = 0;
};
//具体工厂
class CircleFactory :public ShapeFactory
{
public:
	Shape* getShape()override
	{
		return new Circle;
	}
};
class RectangleFactory :public ShapeFactory
{
public:
	Shape* getShape()override
	{
		return new Rectangle;
	}
};
class TriangleFactory :public ShapeFactory
{
public:
	Shape* getShape()override
	{
		return new Triangle;
	}
};
int main()
{
	ShapeFactory* shapeFactory1 = new CircleFactory;
	Shape* shape1 = shapeFactory1->getShape();
	shape1->draw();

	ShapeFactory* shapeFactory2 = new RectangleFactory;
	Shape* shape2 = shapeFactory2->getShape();
	shape2->draw();

	ShapeFactory* shapeFactory3 = new TriangleFactory;
	Shape* shape3 = shapeFactory3->getShape();
	shape3->draw();

	return 0;
}

抽象工厂模式

抽象工厂模式提供了一个接口,用于创建一系列相关或相互依赖的对象。抽象工厂模式是工厂方法模式的扩展,它允许客户端通过工厂接口来创建多个产品族。

cpp 复制代码
#include <iostream>
#include <map>
#include <vector>
#include <string>
using namespace std;

//抽象工厂模式
// 产品接口
class Shape 
{
public:
	virtual void draw() const = 0;
	virtual ~Shape() {}
};

class Color 
{
public:
	virtual void fill() const = 0;
	virtual ~Color() {}
};

// 具体产品
class Circle : public Shape 
{
public:
	void draw() const override 
	{
		std::cout << "Drawing a Circle" << std::endl;
	}
};

class Rectangle : public Shape 
{
public:
	void draw() const override 
	{
		std::cout << "Drawing a Rectangle" << std::endl;
	}
};

class Triangle : public Shape
{
public:
	void draw() const override 
	{
		std::cout << "Drawing a Triangle" << std::endl;
	}
};

class Red : public Color 
{
public:
	void fill() const override 
	{
		std::cout << "Filling with Red" << std::endl;
	}
};

class Green : public Color 
{
public:
	void fill() const override 
	{
		std::cout << "Filling with Green" << std::endl;
	}
};

// 抽象工厂
class AbstractFactory 
{
public:
	virtual Shape* createShape(const string& shapeType) const = 0;
	virtual  Color* createColor(const string& colorType) const = 0;
	virtual ~AbstractFactory() {}
};
class ShapeColorFactory :public AbstractFactory
{
public:
	Shape* createShape(const string& shapeType) const override
	{
		if (shapeType == "Circle")
		{
			return new Circle;
		}
		else if (shapeType == "Rectangle")
		{
			return new Rectangle;
		}
		else if (shapeType == "Triangle")
		{
			return new Triangle;
		}
		else
		{
			//..
		}
	}
	Color* createColor(const string& colorType) const override
	{
		if (colorType == "Red")
		{
			return new Red;
		}
		else if (colorType == "Green")
		{
			return new Green;
		}
		else
		{
			//...
		}
	}
};
int main()
{
	AbstractFactory* factory = new ShapeColorFactory;
	Shape* shape1 = factory->createShape("Circle");
	Shape* shape2 = factory->createShape("Triangle");

	Color* color1 = factory->createColor("Red");
	Color* color2 = factory->createColor("Green");

	shape1->draw();
	color1->fill();

	shape2->draw();
	color2->fill();

	return 0;
}
相关推荐
美丽的欣情5 分钟前
Qt实现海康OSD拖动Demo
开发语言·qt
C++小厨神39 分钟前
Bash语言的计算机基础
开发语言·后端·golang
BinaryBardC41 分钟前
Bash语言的软件工程
开发语言·后端·golang
飞yu流星1 小时前
C++ 函数 模板
开发语言·c++·算法
没有名字的鬼1 小时前
C_字符数组存储汉字字符串及其索引
c语言·开发语言·数据结构
专注于开发微信小程序打工人1 小时前
庐山派k230使用串口通信发送数据驱动四个轮子并且实现摄像头画面识别目标检测功能
开发语言·python
土豆凌凌七1 小时前
GO:sync.Map
开发语言·后端·golang
Goldinger1 小时前
vscode 配置c/c++环境 中文乱码
c语言·c++·vscode
重剑无锋10241 小时前
【《python爬虫入门教程12--重剑无峰168》】
开发语言·爬虫·python
nSponge2 小时前
【Duilib】 List控件支持多选和获取选择的多条数据
c++·windows·工具