c++ - 如何在不修改uml图c ++的情况下实现向对象添加价格
问题描述
我不知道如何实现向菜单添加价格,所以我不更改 uml 图表。
要求说明:
抽象类
Menu
有一个纯虚方法description()
。
Withlemon
并Withcoffee
包含一个菜单和方法description()
,在包含的菜单的描述中添加文本“With lemon”,分别为“with coffee”。
包含柠檬的菜单价格增加 4,包含咖啡的菜单价格增加 5。
该类Breakfast
是没有柠檬和没有咖啡的菜单,方法 description() 返回菜单的名称。
在比萨店餐厅里有2个小菜早餐:鸡蛋和煎蛋卷,价格10和15。仅创建从 UML 图产生的方法和属性(只需添加特定的 C ++ 例如:构造函数)。
这是我的代码:
#include <iostream>
using namespace std;
class Menu {
private:
int price = 0;
public:
virtual string description() = 0;
int getPrice() {
return price;
}
};
class WithLemon : public Menu {
private:
Menu* meniu;
public:
WithLemon() = default;
WithLemon(Menu* n) :
meniu{ n } {}
string description() {
return meniu->description() + " with lemon ";
}
};
class WithCoffee : public Menu {
private:
Menu* meniu;
public:
WithCoffee(Menu* n) :
meniu{ n } {
}
string description() {
return meniu->description() + " with coffee ";
}
};
class Breakfast : public Menu {
private:
string name;
public:
Breakfast(string n) :
name{ n } {
}
string description() {
return name;
}
};
int main() {
Breakfast a{"eggs"};
WithCoffee transformer1{ &a };
transformer1 = &a;
cout << transformer1.description() << " " << transformer1.getPrice() << endl;
return 0;
}
解决方案
图表的问题
首先,图表与叙述不符:
- 已经有 a
price
和 a 了getPrice()
。因此,您可以完全按照 description() 的方式进行操作:只需提供您自己的实现即可。 - 然后,它并没有表明它
description
是纯虚拟的Menu
:该操作应该以斜体显示。 - 此外,既然
WithLemon
,WithCoffee
并Breakfast
提供他们自己的具体实现description()
,它也应该在这些类中显示。
提示 :WithLemon
andWithCoffee
是. _Menu
代码问题
在基类Menu
中,由于您有一个虚函数,因此最好给它一个虚析构函数。由于您有一个价格并且之后无法更改它,因此它应该包含在构造函数中:
class Menu {
private:
int price;
public:
Menu(int p=0) : price{p} {}
...
virtual ~Menu() {}
};
现在您还应该在构造时再次提供price
, in , 。Breakfast
一个小建议:无论何时从基类重写虚函数,使用关键字override
; 它将为您节省数小时的 nastry 错误调试时间:
class Breakfast : public Menu {
private:
string name;
public:
Breakfast(string n, int p) :
name{ n }, Menu{ p} {
}
string description() override {
return name;
}
};
您已经很好地实现了装饰器。override
出于同样的原因,我只是建议添加关键字。
最后,为了满足所有要求,在不与类图相矛盾的情况下,您可以使getPrice()
virtual:它不是纯虚函数,因为您在 base 中提供了默认实现Menu
。在装饰器中,您只需用更专业的方法覆盖该方法:
class WithCoffee : public Menu {
private:
Menu* meniu;
public:
WithCoffee(Menu* n) :
meniu{ n } {
}
string description() override{
return meniu->description() + " with coffee ";
}
int getPrice() override{
return meniu->getPrice()+5;
}
};
在我看来,这种覆盖应该显示在图表中。但是由于您的老师没有显示抽象方法的覆盖(这更重要),他/她不能抱怨在您的代码中覆盖了提供默认实现的方法。
最后,您可以测试一下:
Breakfast a{"eggs", 10};
WithCoffee breakfast_with_coffee { &a };
cout << breakfast_with_coffee.description() << " " << breakfast_with_coffee.getPrice() << endl;
这里是在线演示。
重要提示: 这当然仅用于学习目的。在现实世界中,你有办法改变价格。此外,decroators 不会只添加硬编码的文本和金额。最后,您可能会使用智能指针,而不是容易出错的原始指针。
推荐阅读
- r - 所有 .png 大小的总和
- grafana - Grafana 获得额外的 \\ 之前。我的变量名中的运算符
- c# - 唯一列表以及每个数字在原始列表中出现的次数
- rsync - 用于 rsync 文件的 SLURM 作业脚本
- powershell - 使用 powershell 将 csv 文件与 windows-1252 编码结合起来
- javascript - 如何在 p5.js 中触发关键事件
- c# - 在 AngularDateRangePicker 中使用 Moment
- docker - 连接期间出错:获取 http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/json:读取 unix @->/var/run/docker.sock:读取:对等方重置连接
- python - Python可以更快地获取网站截图吗?
- python - 使用 subprocess.run 执行 windows 命令时,输出流中的 Unicode 字符替换为问号