装饰模式(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++虚函数表。