装饰者模式

最近看《深入浅出设计模式》,记录一下学习经验,也分享给和我一样的初学者,书中举了一个例子,假设现在有一家饮料店,销售各种各样的饮料,比如饮料:咖啡,牛奶,汽水等等,而这些饮料还可以和不同的调料进行组合,产生新的饮料,比如调料:冰、奶糖、果冻等。该模式的优点在于,当饮料店增加新的饮料和配料时,可以在不改动之前的源码的基础上进行扩展,及设计模式中的要点:对扩展开放,对修改关闭。

咋们先看看类图大笑



接下来看看源码:

#include <iostream>
#include <string>

using namespace std;

//饮料
class Beverage
{
public:
	string description;

	Beverage(): description("Unknow Beverage")
	{
		cout << "Create Beverage" << endl;
	}
	virtual ~Beverage()
	{
		cout << "Delete Beverage" << endl;
	}

	virtual int cost() = 0;
	virtual string getDescription() = 0;
};

//佐料装饰类
class CondimentDecorator : public Beverage
{
public:
	CondimentDecorator()
	{
		cout << "Create CondimentDecorator" << endl;
	}

	virtual ~CondimentDecorator()
	{
		cout << "Delete CondimentDecorator" << endl;
	}

	virtual int cost() = 0;
	virtual string getDescription() = 0;

};

//一种具体的饮料
class Milk : public Beverage
{
public:
	Milk()
	{
		description = "Milk";
		cout << "Create Milk" << endl;
	}

	~Milk()
	{
		cout << "Delete Milk" << endl;
	}

	string getDescription()
	{
		return description;
	}

	int cost()
	{
		return 2;
	}
};

//牛奶装饰佐料
class Ice : public CondimentDecorator
{
public:
	Ice(Beverage *beverage)
	{
		this->beverage = beverage;
		cout << "Create Ice" << endl;
	}

	~Ice()
	{
		cout << "Delete Ice" << endl;
	};

	int cost()
	{
		return 1 + beverage->cost();
	}

	string getDescription()
	{
		return beverage->description + "Ice";
	}

	Beverage *beverage; 
};

int main()
{
	int i = 0;
	Beverage *beverageHouseBlend = NULL;
	Beverage *beverage = new Milk;

	beverageHouseBlend = beverage;
	beverage = new Ice(beverage);	//牛奶里加冰

	cout << beverage->getDescription() + ": " << beverage->cost() << endl;

	delete beverage;
	delete beverageHouseBlend;

	cin >> i;
	return 0;
}

很少使用C++实际编程,编写这里例子的时候遇到了一些麻烦,和大家分享一下其中 的一些C++概念。

1、虚函数与纯虚函数:

virtual ~Beverage(){}//虚函数

virtual int cost() = 0; //纯虚函数

通俗的区别,虚函数需要实现函数体,而纯虚函数不需要实现函数体,进而在继承基类时,派生类必须重写纯虚函数,可以不重新虚函数,直接使用父类的虚函数。

2、构造函数不能为虚函数:

虚函数的意思就是开启动态绑定,在调用构造函数时,对应的对象还未完全创建,无法进行动态绑定,因此构造函数不能为虚函数。

3、基类的析构函数为虚函数:

当我们使用基类指针释放派生类时,才能调用正确的析构函数。

4、派生类初始化列表无法初始化基类成员变量

因为在“初始化列表”中初始化成员变量时,此时还没有调用基类的构造函数,也就是说基类还未完成创建,因此想在派生类构造时改变基类变量值,就只有在派生类的构造函数中赋值了。

5、构造与析构顺序


	从图中,我们可以看出,在构造时,在创建一个派生类对象时,需要先构造它的父类对象,在析构一个派生类对象时,最后析构父类对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值