【发布时间】:2020-03-31 05:26:42
【问题描述】:
我刚刚了解了装饰器模式,并尝试编写一个使用该代码的示例。这个例子是关于饮料和一些调味品的。在装饰器中,我有一个饮料的引用变量。提供的饮料是Decaf 和Espresso。可用的调味品是Soy 和Caramel。例如,如果我用多个Caramel 定义一个Decaf,我得到的结果只是一个带有一个装饰器的Decaf。所以定义Caramel->Caramel->Decaf给我Caramel->Decaf。定义Caramel->Soy->Caramel->Decaf 工作正常。定义Caramel->Soy->Caramel->Caramel->Decaf给我Caramel->Soy->Caramel->Decaf。长话短说,我不能一个接一个地吃两种或多种相同类型的调味品。它们只是一种调味品。如果我使用指针,它工作正常。
代码:
#include <iostream>
//#include "Decaf.h"
//#include "Espresso.h"
//#include "SoyDecorator.h"
//#include "CaramelDecorator.h"
class Beverage
{
public:
virtual std::string GetDescription() const = 0;
virtual int GetCost() const = 0;
};
class CondimentDecorator : public Beverage
{
public:
Beverage& beverage;
CondimentDecorator(Beverage& beverage) : beverage(beverage) {}
};
class Espresso : public Beverage
{
virtual std::string GetDescription() const override
{
return "Espresso";
}
virtual int GetCost() const override
{
return 5;
}
};
class Decaf : public Beverage
{
virtual std::string GetDescription() const override
{
return "Decaf";
}
virtual int GetCost() const override
{
return 4;
}
};
class CaramelDecorator : public CondimentDecorator
{
public:
CaramelDecorator(Beverage& beverage) : CondimentDecorator(beverage) {}
virtual std::string GetDescription() const override
{
return this->beverage.GetDescription() + " with Caramel";
}
virtual int GetCost() const override
{
return this->beverage.GetCost() + 2;
}
};
class SoyDecorator : public CondimentDecorator
{
public:
SoyDecorator(Beverage& beverage) : CondimentDecorator(beverage) {}
virtual std::string GetDescription() const override
{
return this->beverage.GetDescription() + " with Soy";
}
virtual int GetCost() const override
{
return this->beverage.GetCost() + 1;
}
};
int main()
{
Decaf d;
SoyDecorator s(d);
CaramelDecorator c(s);
CaramelDecorator cc(c);
std::cout << cc.GetDescription() << std::endl;
std::cout << cc.GetCost() << std::endl;
}
输出:
Decaf with Soy with Caramel
7
// Expected:
// Decaf with Soy with Caramel with Caramel
// 9
这是相同的代码,但使用指针并且工作正常: https://ideone.com/7fpGSp
【问题讨论】:
-
如果您调用
CaramelDecorator cc(c);,则使用(默认)复制构造函数。您可以删除它以达到您的目的。 (我假设你不需要它。)
标签: c++ pointers reference decorator