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

How to create a decorator function without using virtual

本文关键字:创建 情况下 函数 虚拟      更新时间:2023-10-16

我必须使用基于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();
}

我很确定我的代码反映了装饰器模式(如果没有,请告诉我(,但我不确定如何根据字符串返回价格。除此之外,UML 图指定 BasicSmoothy 有两种类型,具有两种特定价格(Kiwi 10$,Strawberry 12$(,派生类在最终列出的价格上分别增加 2$ 和 3$。

有没有办法通过函数 getPrice(( 返回价格,而不需要它是虚拟的,也没有在其他类中实现它?

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

#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;

}
相关文章: