Jan Turoň
Jan Turoň

Reputation: 32912

Should we use decorator pattern in C++?

No doubt that decorator pattern is good and easy standard to enhance some method in class which can't (or shouldn't) inherit the one with old method, like in this example in C# (I am not using interface (I should) to make it as short as possible).

using System;

class Human { ... }

class Father {
    public string Info() {
        return "John";
    }
}

class Son : Human { // decorating Father
    Father f = new Father();
    public string Info() {
        return "I am son of "+f.Info();
    }
}


class Program {
    public static void Main() {
        Son s = new Son();
        Console.WriteLine(s.Info()); // I am son of John
        Console.ReadKey();
    }
}

But since we have multiple inheritance in C++, we can hide Fathers' Info() instead of decorate it:

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

class Human { ... };

class Father {
public:
    string Info() {
        return "John";
    }
};

class Son : public Human, Father { // inherit both
public:
    string Info() {
        return "I am son of " + Father::Info();
    }
};

int main() {
    Son* s = new Son();
    cout << s->Info(); // I am son of John
    cin.get();
    return 0;
}

I understand that the reason for many patterns is to move the ad-hoc logic from reusable class to ad-hoc class, so the reusable class does not need to be (or can't be) messed with ad-hoc code. But this can be achieved with multiple inheritance, too.

So can you explain (or give an example) where decoration is better idea than multiple inheritance?

Upvotes: 0

Views: 289

Answers (2)

mindandmedia
mindandmedia

Reputation: 6825

In my opinion, this is not the decorator pattern and you seem to be using inheritance the wrong way. Before inheriting, ask yourself, if the statement holds true: "Son is a Father" or SpecificObject is a GeneralizedObject, which is not what you ment to express.

The decorator pattern works by passing the object to be decorated to the object that decorates it. A typcial example is the BorderClass in Gui's that decorates the widget you pass it with a border.

 public class Border : Widget
   { 
       public Border(Widget decorateMe)
       { 
          this._toDecorate = decorateMe;
       }
       public virtual void draw(gc or whatnot){
          gc.drawRectangle(blah);
          this._toDecorate.draw(gc);
       }
   }

hope this helps

Upvotes: 0

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76828

With the decorator pattern you can decorate objects at run-time, while multiple inheritance is a compile-time solution. This allows you to freely combine different decorators with minimal overhead, whereas with multiple inheritance, you need a new class for each combination of decorators.

Also, multiple inheritance is hard to get right if you are inheriting anything but interface-classes (classes that only have pure virtual methods).

Upvotes: 4

Related Questions