 // Purpose.  Decorator.  Use aggrega-   #include <iostream.h>
 // tion instead of inheritance to im-
 // plement embellishments to a "core"   class I { public:
 // object.  Client can dynamically         virtual ~I() { }
 // compose permutations, instead of        virtual void doIt() = 0;
 // the architect statically wielding    };
 // multiple inheritance.
                                         class A : public I { public:
 #include <iostream.h>                      ~A() { cout << "A dtor" << endl; }
                                            /* virtual */ void doIt() {
 class A { public:                             cout << 'A'; }
    virtual void doIt() {                };
       cout << 'A'; }
 };                                      class D : public I {
                                         public:
 class AwithX : public A { public:          D( I* core ) { core_ = core; }
    /* virtual */ void doIt() {             ~D()         { delete core_; }
       A::doIt();                           /* virtual */ void doIt() {
       doX(); }                                core_->doIt(); }
 protected:                              private:
    void doX() { cout << 'X'; }             I* core_;
 };                                      };

 class AwithY : public A { public:       class X : public D { public:
    /* virtual */ void doIt() {             X( I* core ) : D(core) { }
       A::doIt();                           ~X() { cout << "X dtor" << endl; }
       doY(); }                             /* virtual */ void doIt() {
 protected:                                    D::doIt();  cout << 'X'; }
    void doY() { cout << 'Y'; }          };
 };
                                         class Y : public D { public:
 class AwithZ : public A { public:          Y( I* core ) : D(core) { }
    /* virtual */ void doIt() {             ~Y() { cout << "Y dtor" << endl; }
       A::doIt();                           /* virtual */ void doIt() {
       doZ(); }                                D::doIt();  cout << 'Y'; }
 protected:                              };
    void doZ() { cout << 'Z'; }
 };                                      class Z : public D { public:
                                            Z( I* core ) : D(core) { }
 class AwithXY : public AwithX,             ~Z() { cout << "Z dtor" << endl; }
                 public AwithY {            /* virtual */ void doIt() {
 public:                                       D::doIt();  cout << 'Z'; }
    /* virtual */ void doIt() {          };
       AwithX::doIt();
       AwithY::doY(); }                  void main( void )
 };                                      {
                                            I* anX = new X( new A );
 class AwithXYZ : public AwithX,            I* anXY = new Y( new X( new A ) );
                  public AwithY,            I* anXYZ = new Z( new Y( new X(
                  public AwithZ {                       new A ) ) );
 public:                                    anX->doIt();    cout << endl;
    /* virtual */ void doIt() {             anXY->doIt();   cout << endl;
       AwithX::doIt();                      anXYZ->doIt();  cout << endl;
       AwithY::doY();
       AwithZ::doZ(); }                     delete anX;
 };                                         delete anXY;
                                            delete anXYZ;
 void main( void )                       }
 {
    AwithX    anX;                       // AX             // X dtor
    AwithXY   anXY;                      // AXY            // A dtor
    AwithXYZ  anXYZ;                     // AXYZ           // Z dtor
    anX.doIt();    cout << endl;         // X dtor         // Y dtor
    anXY.doIt();   cout << endl;         // A dtor         // X dtor
    anXYZ.doIt();  cout << endl;         // Y dtor         // A dtor
 }

