裝飾模式(Decorator)
動態給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比產生子類更靈活。
// FineryTest01.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <iostream>#include <string>using namespace std;class Person{private : char* name;public : Person(){ name = 0; } ~Person() { if(name != 0) { delete []name; } } Person(char* name) { //this->name = name; char* p = name; int len = 0; while(*p != 0) { p++; len++; } this->name = new char[len + 1]; memcpy(this->name, name, len+1); } virtual void Show() { cout<<"裝扮的"<<this->name<<endl; }};//服飾類class Finery : public Person{protected : Person *person;public : void Decorate(Person *p) { this->person = p; } virtual void Show() { if(person != NULL) { person->Show(); } }};//具體服飾類class TShirts : public Finery{public : virtual void Show() { cout<<" [大T恤] "; Finery::Show(); }};class BigTrouser : public Finery{public : virtual void Show() { cout<<" [垮褲] "; Finery::Show(); }};class Sneaker : public Finery{public : virtual void Show() { cout<<" [運動鞋] "; Finery::Show(); }};int _tmain(int argc, _TCHAR* argv[]){ char* name = "小菜"; Person per(name); cout<<"第一種裝扮:"<<endl; BigTrouser bt; TShirts ts; Sneaker sn; bt.Decorate(&per); ts.Decorate(&bt); sn.Decorate(&ts); sn.Show(); system("pause"); return 0;}
程式啟動並執行結果:
第一種裝扮: [運動鞋] [大T恤] [垮褲] 裝扮的小菜
這個程式中需要注意的是,使用C#編程時,在具體服飾類裡調用base.Show(),即調用基類同名方法,實際上調用的是被重寫的方法。而使用C++,需要將所有Show函數全部加上virtual關鍵字,它才能找到上一次執行個體化對象時所填充的函數。具體細節去看C++虛函數表。