Как создать функцию декоратора без использования виртуального - PullRequest
1 голос
/ 10 июля 2019

Я должен использовать шаблон Decorator, основанный на диаграмме UML.В зависимости от типа вводимой строки, я должен вернуть цену и описание.Проблема, с которой я сталкиваюсь, заключается в том, что в описании UML строго указывается, что функция цены не является виртуальной, и, кроме того, ее следует реализовывать только в интерфейсе Smoothy, как показано ниже в коде:


#include<iostream>
using namespace std;

class Smoothy{
    int price;
public:
    int getPrice(){
        return price;
    }
    virtual ~Smoothy() = default;
    virtual string description() = 0;
};

class BasicSmoothy: public Smoothy{
private:
    string nume;
public:
    BasicSmoothy(string n): nume(n){}
    string description(){
        return nume;
    }
};

class SmoothyDecorator:public Smoothy{
private:
    Smoothy *b;

public:
    SmoothyDecorator(Smoothy* bb){
      b = bb;
    }
    ~SmoothyDecorator(){
        delete b;
    }
    string description(){
        return b->description();
    }
};

class SmoothyWithCream:public SmoothyDecorator{
public:
    SmoothyWithCream(Smoothy *b):SmoothyDecorator(b){

    }
    string description(){

        return SmoothyDecorator::description() + " with Cream!";
    }
};

class SmoothyWithCinnamon:public SmoothyDecorator{
public:
    SmoothyWithCinnamon(Smoothy *b):SmoothyDecorator(b){

    }
    string description(){
        return SmoothyDecorator::description() + " with Cinnamon!";

    }
};

int main(){
     Smoothy* b = new SmoothyWithCinnamon(new BasicSmoothy("Kiwi"));
     cout<<b->description();

}

Я уверен, что мой код отражает шаблон Decorator (пожалуйста, дайте мне знать, если это не так), но я не уверен, как вернуть цену, основанную на строке.В дополнение к этому на диаграмме UML указано, что BasicSmoothy имеет два типа, с двумя конкретными ценами (киви 10 $, клубничный 12 $) и классы Derived каждый добавляют 2 $ и 3 $ к окончательной указанной цене.

Есть ли способ вернуть цену через функцию getPrice (), если она не виртуальна и не реализована в других классах?

Ответы [ 2 ]

1 голос
/ 10 июля 2019

Вы можете сделать цену защищенной и перезаписать ее в декораторе:

#include<iostream>
using namespace std;

class Smoothy{
protected:
    int price;
public:
    int getPrice(){
        return price;
    }
    virtual ~Smoothy() = default;
    virtual string description() = 0;
};

class BasicSmoothy: public Smoothy{
private:
    string nume;
public:
    BasicSmoothy(string n): nume(n) {
        if (nume == "Kiwi") {
            price = 10;
        } else if (nume == "Strawberry") {
            price = 12;
        } else {
            throw;
        }
    }
    string description(){
        return nume;
    }
};

class SmoothyDecorator:public Smoothy{
private:
    Smoothy *b;

public:
    SmoothyDecorator(Smoothy* bb){
      b = bb;
    }
    ~SmoothyDecorator(){
        delete b;
    }
    string description(){
        return b->description();
    }
};

class SmoothyWithCream:public SmoothyDecorator{
public:
    SmoothyWithCream(Smoothy *b):SmoothyDecorator(b){
        price = b->getPrice() + 2;
    }
    string description(){

        return SmoothyDecorator::description() + " with Cream!";
    }
};

class SmoothyWithCinnamon:public SmoothyDecorator{
public:
    SmoothyWithCinnamon(Smoothy *b):SmoothyDecorator(b) {
        price = b->getPrice() + 3;
    }
    string description(){
        return SmoothyDecorator::description() + " with Cinnamon!";

    }
};

int main(){
    Smoothy* b = new SmoothyWithCinnamon(new BasicSmoothy("Kiwi"));
    cout<<b->description() << std::endl;
    cout << b->getPrice();
}
0 голосов
/ 12 июля 2019

Для любого любопытного мне удалось найти решение.

class Smoothy
{

public:

    Smoothy()
    {

    }

    Smoothy(int n):
        price(n)
    {
    };

    virtual ~Smoothy() = default;

    int getPrice()
    {
        return price;
    }

    virtual string description() = 0;

private:

    int price;
};


class BasicSmoothy :
    public Smoothy
{
public:

    BasicSmoothy(string n) :
        Smoothy(n=="Kiwi"?10:12),
        nume(n)
    {
    }

    string description()
    {
        return nume;
    }

private:

    string nume;
};

class SmoothyDecorator :
    public Smoothy
{
public:

    SmoothyDecorator(Smoothy* bb, int pret) :
        Smoothy(pret + bb->getPrice()), b(bb)
    {

    }

    ~SmoothyDecorator()
    {
        delete b;
    }

    string description()
    {
        return b->description();
    }

private:

    Smoothy* b;
};

class SmoothyWithCream :
    public SmoothyDecorator
{
public:

    SmoothyWithCream(Smoothy* b) :
        SmoothyDecorator(b, 2)
    {
    }

    virtual string description()
    {
        return SmoothyDecorator::description() + " with Cream!" + to_string(getPrice());
    }
};

class SmoothyWithCinnamon :
    public SmoothyDecorator
{
public:

    SmoothyWithCinnamon(Smoothy* b) :
        SmoothyDecorator(b, 3)
    {
    }

    virtual string description()
    {
        return SmoothyDecorator::description() + " with Cinnamon!" + to_string(getPrice());
    }
};

int main()
{
    Smoothy* b1 = new SmoothyWithCinnamon(new SmoothyWithCream(new BasicSmoothy("Kiwi")));
    Smoothy* b2 = new SmoothyWithCinnamon(new SmoothyWithCream(new BasicSmoothy("Strawberry")));

    cout <<b1->description() << std::endl;
    cout <<b2->description() << std::endl;

    delete b1;
    delete b2;


}

...