4
\$\begingroup\$

I wrote a version of decorator pattern in c++ as I wasn't able to find any good source of decorator pattern implementation in C++. I want to know if I implemented it correctly. Here is the code-

//implementing the pizza example in c++

#include "bits/stdc++.h"
using namespace std;

class Pizza{
protected:
    string description = "";
    int cost = 0;
public:
    string getdescription(){
        return description;
    }
    int getcost(){
        return cost;
    }
};
//pizzas
class PeppyPaneer: public Pizza{
public:
    PeppyPaneer(){
        cost = 100;
        description = description + " PeppyPaneer";
    }
};
class Magharita: public Pizza{
public:
    Magharita(){
        cost = 200;
        description = description + " Magharita";
    }
};

//toppings
class Barbeque: public Pizza{
public:
    Barbeque(Pizza *pizza){
        cost = pizza->getcost() + 50;
        description = pizza->getdescription()+ " Barbeque";
    }
};

class Paneer: public Pizza{
public:
    Paneer(Pizza *pizza){
        cost = pizza->getcost() + 60;
        description = pizza->getdescription() + " Paneer";
    }
};


int main(){

    Pizza *pizza = new PeppyPaneer();
    cout << pizza->getcost() << " " << pizza->getdescription() << "\n";

    pizza = new Barbeque(pizza);
    cout << pizza->getcost() << " " << pizza->getdescription() << "\n"; 

    pizza = new Paneer(pizza);
    cout << pizza->getcost() << " " << pizza->getdescription() << "\n";


    return 0;
}
\$\endgroup\$
  • \$\begingroup\$ Inheritance is not the same as a decorator. \$\endgroup\$ – Martin York Aug 28 '17 at 17:46
7
\$\begingroup\$

Here are some comments on your code and design.

Don't abuse using namespace std

Putting using namespace std at the top of every program is a bad habit.

Use the required #includes

The code uses std::string which means that it should #include <string>. It also needs #include <iostream>.

Don't #include headers that aren't needed

The inverse of the advice above is to not include header files that are not needed. In this case, "bits/stdc++.h" should be removed. It's not standard and will only increase compilation times, so you should probably avoid it in favor of using the standard #includes as actually needed.

Don't leak memory

Each time your code in main creates a new pizza, it loses any pointer to the old one, making it a certainty that memory is leaked. There are two ways to deal with that. One is to use delete to match each new. Another alternative is to use smart pointers instead.

C++ isn't Java

Code like this looks more like Java than idiomatic C++:

std::string getdescription(){
    return description;
}
int getcost(){
    return cost;
}

Instead of writing generic getters and setters in the Java style, write idiomatic C++ instead:

std::string desc() const {
    return m_description;
}
int cost() const {
    return m_cost;
}

Here I've used a relatively common idiom of prefixing class variables with m_ and omitting the word get. Additionally, both functions are declared const because they do not alter the underlying object.

Reread the decorator pattern description

I don't think your code actually faithfully implements the decorator pattern. Consider instead a revision to your pizza model in which a new pizza retains a reference to the underlying basic pizza model passed to the constructor. That would be a better potential illustration for the use of a decorator pattern. See https://en.wikipedia.org/wiki/Decorator_pattern for more details.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.