如何在不使用 virtual 的情况下创建装饰器函数

How to create a decorator function without using virtual

我必须使用基于 UML 图的装饰器模式。根据我输入的字符串类型,我必须 return 一个价格和一个描述。我遇到的问题是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 模式(如果没有反映,请告诉我),但我不确定如何 return 基于字符串的价格。除此之外,UML 图指定 BasicSmoothy 有两种类型,有两种特定价格(Kiwi 10$,Strawberry 12$)和 Derived 类 分别在最终列出的价格上增加 2$ 和 3$。

有没有办法通过函数 getPrice() return 价格而不用它是虚拟的并且不用在另一个 类 中实现它?

你可以保护价格并在装饰器中覆盖它:

#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();
}

对于任何好奇的人,我设法找到了解决方案。

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;


}