vendredi 13 novembre 2020

Implementation of the decorator class in C++ using a member reference to the decorated object not working as expected

I am trying to learn the decorator pattern implementation in C++. I have tried implementing the decorator class using both a reference and pointer to the decorated object as a member (composition). A single invocation of decorator works expectedly. However, when I try chaining together multiple decorator instances, it works only when I use the pointer to the decorated object as a decorator class member. For the implementation with the decorated object reference, it fails unexpectedly (please see the output below). I am using GCC with C++11 enabled. Here's the code. The class RedRose is a decorator using the pointer to the base interface while class BlueRose uses the reference to the base interface. I am sorry if I am making a naive mistake but what am I missing?

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

class Flower
{
public:
    Flower() {}
    virtual string str() = 0;
};

class Rose : public Flower
{
public:
    Rose() {}
    
    string str() override {
        return "A rose";
    }
};

class RedRose : public Rose
{
private:
  Flower *rose;

public:
  explicit RedRose(Flower *rose) : rose{rose} {}
  
  string str() override
  {
      ostringstream oss;
      oss << rose->str() << " that is red ";
      return oss.str();
  } 
};

class BlueRose : public Rose
{
private:
  Flower &rose;

public:
  explicit BlueRose(Flower &rose) : rose{rose} {}
  
  string str() override
  {
      ostringstream oss;
      oss << rose.str() << " that is blue";
      return oss.str();
  } 
};

int main(int argc, char *argv[])
{
    
    Rose rose; // The decorated object
    
    // Chaining together docorator with pointer implementation
    RedRose red_rose{&rose};
    RedRose red_red_rose{&red_rose};
    RedRose red_red_red_rose{&red_red_rose};
    
    cout << red_rose.str() << endl;
    cout << red_red_rose.str() << endl;
    cout << red_red_red_rose.str() << endl;
    
    Rose rose2;
    
    // Chaining together docorator with reference implementation
    BlueRose blue_rose{rose2};
    BlueRose blue_blue_rose{blue_rose};
    BlueRose blue_blue_blue_rose{blue_blue_rose};
    
    cout << blue_rose.str() << endl;
    cout << blue_blue_rose.str() << endl;
    cout << blue_blue_blue_rose.str() << endl;
    
    getchar();
}

Here's the output

A rose that is red 
A rose that is red  that is red 
A rose that is red  that is red  that is red 

A rose that is blue
A rose that is blue
A rose that is blue`

Aucun commentaire:

Enregistrer un commentaire