Prototype设计模式理解

Prototype设计模式理解

对于设计模式每一次听完看完都有一种让人觉得十分优雅得感觉


以下是我对这个设计模式得理解(新手理解,还望指正):
首先,由于我们无法预测未来我们所设计得父类在后面会衍生出什么子类,难以去确定子类的名称,但是我们又需要在我们的父类中使用到未来的子类,所以采用此设计模式。下面以代码作为解读.

代码解读

代码片.注:以下代码来自侯捷老师课程

#include <iostream>
using namespace std;
enum imageType
{
	LSAT, SPOT
};
class Image
{
public:
	virtual void draw() = 0;
	static Image* findAndClone(imageType);
protected:
	//两个纯虚函数,让未来的子类能够自己定义实现自己的特征
	virtual imageType returnType() = 0;
	virtual Image* clone() = 0;
	// As each subclass of Image is declared, it registers its prototype
	
	static void addPrototype(Image* image)
	{
		_prototypes[_nextSlot++] = image;
	}
private:
	// addPrototype() saves each registered prototype here
	static Image* _prototypes[10];
	static int _nextSlot;
};
//设计的静态变量或者对象要在类外分配内存
Image* Image::_prototypes[];
int Image::_nextSlot;
// Client calls this public static member function when it needs an instance
// of an Image subclass
//这里我认为写的很美,这个就是父类能够去注册子类的关键
Image* Image::findAndClone(imageType type)
{
	for (int i = 0; i < _nextSlot; i++)
		if (_prototypes[i]->returnType() == type)
			return _prototypes[i]->clone();
}

class LandSatImage : public Image
{
public:
	imageType returnType() {
		return LSAT;
	}
	void draw() {
		cout << "LandSatImage::draw " << _id << endl;
	}
	// When clone() is called, call the one-argument ctor with a dummy arg
	Image* clone() {
		return new LandSatImage(1);
	}
protected:
	// This is only called from clone()
	LandSatImage(int dummy) {
		_id = _count++;
	}
private:
	// Mechanism for initializing an Image subclass - this causes the
	// default ctor to be called, which registers the subclass's prototype
	//这里的静态设置,会默认的调用下面的构造函数,创建一个初始的子类
	static LandSatImage _landSatImage;
	// This is only called when the private static data member is inited
	LandSatImage() {
		addPrototype(this);
	}
	// Nominal "state" per instance mechanism
	int _id;
	static int _count;
};
// Register the subclass's prototype
//由于我们设置的static,所以要在外部声明,那么就会调用默认的构造函数
//默认构造函数会调用addPrototype(this);把自己添加在父类的_prototypes[_nextSlot++] = image;这里也就相当于刚刚开始就会有_prototypes[0]就是LandSatImage 。
LandSatImage LandSatImage::_landSatImage;
// Initialize the "state" per instance mechanism
int LandSatImage::_count = 1;

int main() {
	// 假设我们需要一个LandSatImage类型的图像
	Image* image = Image::findAndClone(LSAT);

	// 使用这个图像实例来绘制图像
	image->draw();

	// 当我们完成图像处理后,释放内存
	delete image;

	return 0;
}

这里面最主要的应该是就类中的静态变量要在外部进行内存的分配,这里我理解了好久,LandSatImage LandSatImage::_landSatImage;这句话十分需要去理解,在类外部使用这句话,也就是刚刚开始的时候Image的_prototypes[0]就是LandSatImage。
原因如下:
在C++中,静态成员变量在程序启动时就会被初始化,即使它们所在的类还没有被显式地使用。因此,LandSatImage::_landSatImage 作为一个静态成员,在程序开始运行时就被初始化了,其构造函数中的 addPrototype(this) 调用确保了 LandSatImage 的原型被添加到了 _prototypes 数组中。

所以,当你执行 Image* image = Image::findAndClone(LSAT); 时,_prototypes 数组已经包含了 LandSatImage 的原型,findAndClone 函数会找到这个原型并调用它的 clone 方法来创建一个新的 LandSatImage 实例。这就是为什么在你调用 findAndClone 方法之前,_prototypes[0] 已经是 LandSatImage 的原因。这个机制允许程序在需要时快速地创建特定类型的 Image 实例,而不需要知道具体的子类信息

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值