装饰器设计模式、功能bug

发布于 2024-11-14 19:16:09 字数 2146 浏览 1 评论 0原文

这是作业...我不是在寻求答案,我只是有一个错误,我不知道该怎么办。谢谢!

所讨论的错误可能与作业本身无关,但无论如何,这里是作业描述:

我正在处理一个作业(在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

想念有你 2024-11-21 19:16:09

您是否也将 currentPizza 声明为 Pizza 类的字段,并且您在其他地方使用它?如果是这样,您在 newPizza 中更新的 currentPizza 是特定于该方法的,您只需执行 currentPizza = new Plain();而不是在方法范围内声明一个新的 currentPizza 变量。

另外,在 addTopping 方法中,您仅更新参数 thisPizza,它是指针副本 当前披萨

你需要做:

currentPizza = addTopping(currentPizza);

Do you have currentPizza also declared as an field of the Pizza class and you are using that somewhere else? If so, the currentPizza you are updating in newPizza is specific to that method, and you need to do just currentPizza = new Plain(); instead of declaring a new currentPizza variable in the scope of the method.

Also, in your addTopping method, you are only updating the argument thisPizza, which is a copy of the pointer currentPizza.

You need to do:

currentPizza = addTopping(currentPizza);
灯角 2024-11-21 19:16:09

如果您按值传递指针(这就是您正在做的事情),它将采用该指针值并将新的披萨分配给它。该值与上面第 7 行中找到的值不同。例如:

int bar = new int(3);
void  doSomething(int *foo){ foo = new int(5); } //memory leak here
doSomething(bar);

bar 仍然是 3。这实际上就是您正在做的事情。

您想通过引用传递指针:

void doSomething(int **foo){ delete *foo; *foo = new int(5); }

更新

看到您想要一个嵌套类结构,其中 Child 类以多态方式保留类 Base 的记录......

void doSomething(MyClass **foo){ *foo = new MyChildClass(*foo); }

我希望作为子类中定义的一部分,您已确保正确处理资源(即指针)的释放。我建议考虑合并一个智能指针,但这可能超出了您完成此任务所需的范围。

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:

int bar = new int(3);
void  doSomething(int *foo){ foo = new int(5); } //memory leak here
doSomething(bar);

bar is still 3. That's effectively what you're doing.

You want to pass in the pointer by reference:

void doSomething(int **foo){ delete *foo; *foo = new int(5); }

Update:

Seeing as you'd like a nested class structure, wherein class Child retains a record of a class Base in a polymorphic manner...

void doSomething(MyClass **foo){ *foo = new MyChildClass(*foo); }

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.

英雄似剑 2024-11-21 19:16:09

一个错误是在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文