装饰器设计模式、功能bug
这是作业...我不是在寻求答案,我只是有一个错误,我不知道该怎么办。谢谢!
所讨论的错误可能与作业本身无关,但无论如何,这里是作业描述:
我正在处理一个作业(在 C++ 中),旨在通过以下方式教授装饰器设计模式的使用:带有配料的披萨的经典例子。 (我的教授也可能直接从 http 中提取它://simplestcodings.com/2010/12/26/decorator-design-pattern-example-ni-c/)。我遇到了一个小问题,我想知道是否有人可以帮助我。
我有一个主菜单(比萨饼店)对象,它接受用户的输入并对比萨饼执行所需的操作。用户从基本的披萨开始,然后可以添加配料,直到完成。因此,我的“newPizza”函数所做的第一件事就是将新的 Pizza 声明为 Plain
,它是抽象类 Pizza
的子类。
然后他们可以输入自己选择的配料。每次,指向同一 Pizza
对象的指针都会发送到 addToppings()
函数,添加新的装饰,然后返回该指针。每个装饰都继承自一个价格类别,该价格类别又继承自 pizzaToppings
,而后者又继承自 Pizza
。
这是主订单函数的相关部分:
Pizza* Menu::newPizza()
{
cout << "\nNew Pizza";
//accept the next choice
int choose = 0;
//create the new pizza
Plain * currentPizza = new Plain();
//until they choose to end the order
while (choose != 3)
{
//accept the choice
cin >> choose;
switch (choose)
{
//if they want to add a new topping
case 1:
{
//add topping to current pizza
//and this is where the problem is spotted by the compiler
addTopping(currentPizza);
break;
}
问题是,当我尝试将指针 currentPizza
发送到函数 addTopping()
时,我得到 “运行时检查失败#3 - 变量‘currentPizza’正在使用但未初始化。”
我不是刚刚在第 7 行初始化了吗?
如果我点击“继续”,程序将继续运行并工作,但每次调用该函数时都会出现相同的错误。这只是某个地方的语法错误,还是我这里有一些实际问题?
谢谢!!
[编辑:]
addTopping() 函数:
Pizza* Menu::addTopping(Pizza* thisPizza)
{
cout << "\nAdd topping";
//declare choose int
int choose = 0;
//accept number of topping
cin >> choose;
//decide which one to add
switch (choose)
{
//mozzarella
case 1:
{
thisPizza = new Mozzarella(thisPizza);
break;
}
//mushrooms
case 2:
{
thisPizza = new Mushrooms(thisPizza);
break;
}
//another 13 possible toppings, won't bore you with the details ;)
}
cout << "\nEnd add topping\n";
return thisPizza;
}
This is homework...I'm not asking for answers, I just have a bug I'm not sure what to do with. Thanks!
The bug in question probably has nothing to do with the assignment itself, but here is the assignment description anyways:
I'm working on an assignment (in C++) meant to teach use of the decorator design pattern through the classic example of a pizza with toppings. (My professor may as well have lifted it straight from http://simplestcodings.com/2010/12/26/decorator-design-pattern-example-ni-c/). I'm running into a little problem that I was wondering if someone could help me with.
I have a main menu(pizzeria) object that takes input from the user and performs the desired actions on a pizza. Users start with a basic pizza and then can add toppings to it until they're done. So the first thing that my "newPizza" function does is declare the new Pizza as a Plain
, which is a subclass of abstract class Pizza
.
Then they get to enter their choice of toppings. Each time, a pointer to the same Pizza
object is sent to the addToppings()
function, the new decoration is added, and the pointer is returned. Each decoration inherits from a price category, which inherits from pizzaToppings
, which inherits from Pizza
.
This is the relevant part of the main order function:
Pizza* Menu::newPizza()
{
cout << "\nNew Pizza";
//accept the next choice
int choose = 0;
//create the new pizza
Plain * currentPizza = new Plain();
//until they choose to end the order
while (choose != 3)
{
//accept the choice
cin >> choose;
switch (choose)
{
//if they want to add a new topping
case 1:
{
//add topping to current pizza
//and this is where the problem is spotted by the compiler
addTopping(currentPizza);
break;
}
The issue is that when I try to send the pointer currentPizza
to the function addTopping()
, I get
"Run-Time Check Failure #3 - The variable 'currentPizza' is being used without being initialized."
Didn't I just initialize it right there on line 7?
If I hit "continue", the program keeps going, and works, but I get that same error every time I call the function. Is it just a syntax error somewhere, or do I have some actual issue here?
Thanks!!
[edit:]
The addTopping() function:
Pizza* Menu::addTopping(Pizza* thisPizza)
{
cout << "\nAdd topping";
//declare choose int
int choose = 0;
//accept number of topping
cin >> choose;
//decide which one to add
switch (choose)
{
//mozzarella
case 1:
{
thisPizza = new Mozzarella(thisPizza);
break;
}
//mushrooms
case 2:
{
thisPizza = new Mushrooms(thisPizza);
break;
}
//another 13 possible toppings, won't bore you with the details ;)
}
cout << "\nEnd add topping\n";
return thisPizza;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否也将
currentPizza
声明为Pizza
类的字段,并且您在其他地方使用它?如果是这样,您在newPizza
中更新的currentPizza
是特定于该方法的,您只需执行currentPizza = new Plain();
而不是在方法范围内声明一个新的currentPizza
变量。另外,在
addTopping
方法中,您仅更新参数thisPizza
,它是指针的副本当前披萨
。你需要做:
Do you have
currentPizza
also declared as an field of thePizza
class and you are using that somewhere else? If so, thecurrentPizza
you are updating innewPizza
is specific to that method, and you need to do justcurrentPizza = new Plain();
instead of declaring a newcurrentPizza
variable in the scope of the method.Also, in your
addTopping
method, you are only updating the argumentthisPizza
, which is a copy of the pointercurrentPizza
.You need to do:
如果您按值传递指针(这就是您正在做的事情),它将采用该指针值并将新的披萨分配给它。该值与上面第 7 行中找到的值不同。例如:
bar 仍然是 3。这实际上就是您正在做的事情。
您想通过引用传递指针:
更新:
看到您想要一个嵌套类结构,其中 Child 类以多态方式保留类 Base 的记录......
我希望作为子类中定义的一部分,您已确保正确处理资源(即指针)的释放。我建议考虑合并一个智能指针,但这可能超出了您完成此任务所需的范围。
If you pass in a pointer by value (which is what you're doing) it will take that pointer value and assign the new pizza to it. That value is not the same as that which is found in line 7 above. For instance:
bar is still 3. That's effectively what you're doing.
You want to pass in the pointer by reference:
Update:
Seeing as you'd like a nested class structure, wherein class Child retains a record of a class Base in a polymorphic manner...
I hope that as part of your definition within the child classes you've made sure you're handling the release of resources (i.e. the pointers) correctly. I'd suggest looking at incorporating a smart pointer but that might be more than you need for this assignment.
一个错误是在
Menu::newPizza()
中你没有这样做:currentPizza = addTopping(currentPizza);
此外,您还遇到了内存泄漏,因为您在堆上创建了新对象,而没有删除旧对象。
顺便说一句,听起来从 addTopping 方法返回新披萨的设计很糟糕。
One mistake is that in
Menu::newPizza()
you do not do this :currentPizza = addTopping(currentPizza);
Also you got a memory leak, since you create new object on heap, without deleting old.
By the way, sounds like a bad design return new pizza from addTopping method.