Reputation: 97
I hope this is not a duplicate, and sorry for my not perfect english.
I'm trying to understand how exactly the decorator pattern works in c++.
I'm using this implementation found online and the design is clear to me.
What i can't understand is how technically it's working.
When i'm creating a new object and decorating it, for example:
AbstractNPC *goblin1= new Elite(new Shaman(new NPC("Goblin")));
The type of goblin1 will be Elite, Shaman, NPC or what?
And how the function render() "takes" the implementation of the other classes and use them together?
I would expect that when i call render(), i'm calling recursively the functions from the other decorator classes using this instruction:
NPCDecorator::render();
Still this doesn't make sense to me.
How and why this works?
Upvotes: 0
Views: 374
Reputation: 62864
The relevant type of goblin1
is right there in the declaration, AbstractNPC *
.
NPCDecorator
implements this abstract class by holding on to another instance of that abstract class. In the expression new Elite(new Shaman(new NPC("Goblin")))
there are three AbstractNPC
instances, two decorators and a "normal" instance.
When the virtual call render
comes into the first decorator, it does it's stuff, then call's its base classes render
, which just delegates to the decorated npc
member.
You will have a call stack like:
Elite::render
{
// this == Elite * @ 0x12345678
cout << "Elite ";
NPCDecorator::render
{
Shaman::render
{
// this == Shaman * @ 0x56781234
cout << "Shaman ";
NPCDecorator::render
{
NPC::render
{
// this == NPC * @ 0x78563412
cout << name; // "Goblin"
}
}
}
}
}
Upvotes: 1