Design Pattern 设计模式 Decorator 装饰者模式

1 设计一个基类

2 继承这个基类,并包含这个基类的一个对象

3 创建继承类的时候,初始化这个基类,因为是基类指针,所以可以是所有基类的衍生类对象,那么就可以叠加任意多个衍生类对象了。


关键是在衍生类中包含一个基类对象,然后有了继承和包含两重关系,可以使得一个类一个类对象叠加,达到装饰目的。

等于是创建了一个对象指针链表,一个一个对象发挥其相应的作用。


下面程序装饰一个桌子,同时包含释放内存的处理。

关键要知道基类的析构函数必须使用虚函数,为什么?

1 如果基类不是析构函数,那么如果衍生类中包含了动态分配地址,那么使用基类指针指向衍生类的时候,就无法正确释放内存了。

2 即使衍生类没有动态释放分配地址,那么增加个virtual也没坏处


#pragma once
#include <string>
#include <iostream>
using namespace std;

//base class
class Desk
{
public:
	virtual string description()
	{
		return "This is a Desk";
	}
	virtual ~Desk() {cout<<endl<<"delete Desk"<<endl;}//这里不使用virtual就无法正确释放内存,所有基类都应该使用virtual
};

//derived class
class ANiceLamp : public Desk
{
	Desk *dk;
public:
	ANiceLamp(Desk *d)
	{
		if (dk) delete dk;//这句显得有点多余,因为一个对象只会创建一次
		dk = d;
	}
	string description()
	{
		return dk->description() + " with A Nice Lamp";
	}
	~ANiceLamp()
	{
		if (dk) delete dk;
		cout<<endl<<"Delete Lamp"<<endl;
	}
};

class Computer : public Desk
{
	Desk * dk;
public:
	Computer(Desk * d)
	{
		if (dk) delete dk;
		dk = d;
	}
	string description()
	{
		return dk->description() + " with the best computer";
	}
	~Computer()
	{
		if (dk) delete dk;
		cout<<endl<<"delete Computer"<<endl;
	}
};

class Flower : public Desk
{
	Desk *dk;
public:
	Flower(Desk *d)
	{
		if (dk) delete dk;
		dk = d;
	}
	string description()
	{
		return dk->description() + " with the most beautiful flower";
	}
	~Flower()
	{
		if (dk) delete dk;
		cout<<endl<<"delete Flower\n";
	}
};

void Decorator3DeskRun()
{
	Desk *desk = new Desk();
	cout<<desk->description()<<std::endl;
	
	desk = new ANiceLamp(desk);
	cout<<desk->description()<<std::endl;
	
	desk = new Computer(desk);
	cout<<desk->description()<<std::endl;

	desk = new Flower(desk);
	cout<<desk->description()<<std::endl;

	desk = new Computer(desk);
	cout<<desk->description()<<std::endl;

	desk = new Flower(desk);
	cout<<desk->description()<<std::endl;
	
	delete desk;
}



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值