改进的装饰者C++

装饰者模式

动态的给对象修改功能。

UML图

改进的装饰者C++_第1张图片

实例代码

#include 
using namespace std;
/* Component (interface) */
class Widget {
public: 
 virtual void draw() = 0; 
 virtual ~Widget() {}
}; 
/* ConcreteComponent */

class TextField : public Widget {
private: 
 int width, height;
public:
 TextField( int w, int h ){ 
 width = w;
 height = h; 
 }

 void draw() { 
 cout << "TextField: " << width << ", " << height << '\n'; 
 }
};
/* Decorator (interface) */ 
class Decorator : public Widget {
private:
 Widget* wid; // reference to Widget
public:
 Decorator( Widget* w ) { 
 wid = w; 
 }
 void draw() { 
 wid->draw(); 
 }
 ~Decorator() {
 delete wid;
 }
};
/* ConcreteDecoratorA */
class BorderDecorator : public Decorator { 
public:
 BorderDecorator( Widget* w ) : Decorator( w ) { }
 void draw() {
 Decorator::draw(); 
 cout << " BorderDecorator" << '\n'; 
 } 
};

/* ConcreteDecoratorB */
class ScrollDecorator : public Decorator { 
public:
 ScrollDecorator( Widget* w ) : Decorator( w ) { }
 void draw() {
 Decorator::draw(); 
 cout << " ScrollDecorator" << '\n';
 } 
};

int main( void ) {
 Widget* aWidget = new BorderDecorator(
 new BorderDecorator(
 new ScrollDecorator(
 new TextField( 80, 24 ))));
 aWidget->draw();
 delete aWidget;
}

问题在哪里?我为什么会感觉扯到蛋了!!!

例子中的operator只有一个draw()。如果有100个operator,我们必须在装饰者类里面把100个都实现一次。

class Decorator : public Widget {
private:
 Widget* wid; // reference to Widget
public:
 Decorator( Widget* w ) { 
 wid = w; 
 }
 void draw() { 
 wid->draw(); 
 }
 void fun1(){
 wid->fun1();
 };
 void fun2(){
 wid->fun2();
 };
 ......
 void fun100(){
 wid->fun100();
 };
 ~Decorator() {
 delete wid;
 }
};

实际上我TM只是想改其中的一个函数draw(),给他加上一个log图形而已。但是其他的funx()必须还是得写,因为装饰者返回了新对象,基类中的数据成员都是空的,未初始化的。不写的话数据就对不上了。所以为了动态修改对象的一个功能,我需要重写这个对象的其他99个方法,是不是分分钟要捏蛋自尽了。

关键问题

装饰者和被装饰者都是继承于同一个父类,有相同的方法,区别在于对象里面的数据不同。那么我能不能把对象里面的数据复制过来?
可以通过memcpy来复制对象里面数据。为啥?因为memcpy可以绕过类的访问权限问题。

#include "iostream"
using namespace std;

class Base
{
public:
    virtual void fun(){
        cout<<"base fun call"<
//不要问我为什么用X,我只是觉得叼而已
class X:public T
{
public:
    X(T *t):_t(t){
        char *dst = (char *)this;
        char *src = (char *)_t;
        memcpy((void *)(dst + sizeof(char *)), (void *)(src + sizeof(char *)), sizeof(T) - sizeof(char *));
    };
    T *getInstance(){
        return this;
    }
//只实现fun函数,不实现printMD
    void fun(){
        _t->fun();
        cout<<"X fun call"<fun();
    a->setInt(5);
    a->printMD();
    cout<<"------after-----"<(a))->getInstance();
    a->fun();
    cout<<"~~~~~~~~~~~~~~~~~"<printMD();

    B *b = new B();
    b = (new X(b))->getInstance();
    b->fun();
    b->printMD();
    return 0;
}

输出结果

------before----

base fun call
A fun call
base say MD: 5
------after-----
base fun call
A fun call
X fun call
~~~~~~~~~~~~~~~~~
base say MD: 5
base fun call
B fun call
X fun call
base say MD: 0

可以看出波浪线下面的base say MD:5,说明成员变量_a被拷贝到装饰者里面去了。但是我的装饰者只实现了fun函数。

你可能感兴趣的:(改进的装饰者C++)