简体   繁体   English

无缘无故通过指针返回的责任链

[英]Chain of responsibility going back by pointers for no reason

So I had a task to do a shop class, products class a basket class bla bla bla, I did all of this, tested, everything is working fine and that has nothing to do with the problem.所以我的任务是开一家商店 class,产品 class 一个篮子 class bla bla bla,我做了所有这些,经过测试,一切正常,与问题无关。 Now what I had to do is create discounts and a chain of responsibility, like let's say I create 3 discounts and it goes through pointers and checks which one is suitable.现在我要做的是创建折扣和一系列责任,比如我创建了 3 个折扣,它会通过指针检查哪个是合适的。 So I did it, it does work, when I was debugging I checked, that it stops on the discount it needs to, returns me the price with the discount applied BUT THEN it somehow is going back by pointers and returning again what I don't need.所以我做到了,它确实有效,当我调试时我检查过,它停止了它需要的折扣,返回给我应用折扣的价格但是它以某种方式通过指针返回并再次返回我没有的东西'不需要。 I will make this more clear after I show the code and I will provide an example.在我展示代码后,我会更清楚地说明这一点,并提供一个示例。 So this is my Discount.h which holds a pointer to the next Discount and the main virtual countDiscount();所以这是我的Discount.h ,它包含一个指向下一个 Discount 和主要虚拟countDiscount(); function that plays the role in all of this. function 在这一切中扮演着重要角色。

#ifndef DISCOUNT_HEADER
#define DISCOUNT_HEADER

#include "Basket.h"

class Discount
{
public:
    Discount():next(NULL){}
    virtual int countDiscount(Basket b) = 0;
    void nextDiscount(Discount* nextDisc) { next = nextDisc; }
protected:
    Discount* next;
};

#endif

So, then I had to do a lot of discount types so I started with a fixated discount, let's say I have FixatedDiscount(100, 15) , so when the person's basket's contents are worth more than 100, then the discount is applied and it just takes 15 away from his total value.所以,然后我不得不做很多折扣类型,所以我从固定折扣开始,假设我有FixatedDiscount(100, 15) ,所以当这个人的购物篮内容价值超过 100 时,就会应用折扣并且它只是从他的总价值中减去 15。 So if he shopped for like 110 then the discount applied and it did 110 - 15= 95. This is the FixatedDiscount.h因此,如果他以 110 的价格购物,则应用折扣,结果为 110 - 15= 95。这是FixatedDiscount.h

#ifndef FIXATED_HEADER
#define FIXATED_HEADER

#include "Discount.h"

class FixatedDiscount:public Discount
{
public:
    FixatedDiscount(int l, int d) : limit{ l }, discount{ d } {}
    int countDiscount(Basket b);
private:
    int limit;
    int discount;
};

#endif

And this is FixatedDiscount.cpp这是FixatedDiscount.cpp

#include "FixatedDiscount.h"
#include <iostream>

int FixatedDiscount::countDiscount(Basket b) {
    int totalPrice = b.countPrice(); //this method just counts the value of the basket which for our example is 120
    if (totalPrice >= limit) {
        totalPrice -= discount;
        std::cout << "Handled when limit is " << limit << " and discount is: " << discount << " returning total price: " << totalPrice << std::endl;
    }
    else if (next != NULL) {
        next->countDiscount(b);
    }
    else {
        std::cout << "I am the last handler" << std::endl;
    }
    return totalPrice;
}

So let's say I had 3 discounts, FixatedDiscount(150, 20);所以假设我有 3 个折扣, FixatedDiscount(150, 20); , FixatedDiscount(100, 15) , FixatedDiscount(50, 10) . , FixatedDiscount(100, 15) , FixatedDiscount(50, 10) In my example I will make a basket that's worth 120, so it should skip the first discount and move on to the second one since he shopped more than 100 and the discount of 15 is applied but he didn't reach 150 to get discount of 20.在我的示例中,我将制作一个价值 120 的篮子,因此它应该跳过第一个折扣并继续进行第二个折扣,因为他购物超过 100 个并且应用了 15 的折扣但他没有达到 150 以获得折扣20.

#include <iostream>
#include "Product.h"
#include "Basket.h"
#include "Discount.h"
#include "FixatedDiscount.h"
#include <vector>

int main()
{
    Product* p1 = new Product("banana", 20, "fruit");
    Product* p2 = new Product("coconut", 35, "fruit");
    Product* p3 = new Product("watermelon", 45, "vegetable");
    Product* p4 = new Product("cucumber", 20, "vegetable");
    Product* p5 = new Product("butter", 30, "dairy");
    Product* p6 = new Product("milk", 40, "dairy");
    std::vector<Product*> catalog{ p1, p2, p3, p4, p5, p6 };

    Basket basket;
    basket.insert(catalog[1]);
    basket.insert(catalog[2]);
    basket.insert(catalog[5]); //All of these 3 products make up to value of 120

    Discount* fixated1 = new FixatedDiscount(150, 20);
    Discount* fixated2 = new FixatedDiscount(100, 15);
    Discount* fixated3 = new FixatedDiscount(50, 10); //made these 3 discounts
    fixated1->nextDiscount(fixated2);
    fixated2->nextDiscount(fixated3); //linked by pointers these 3 discounts
    std::cout << "Price with the discount: " << fixated1->countDiscount(basket) << std::endl;
}

So what is going here is that as you saw in FixatedDiscount.cpp I made a simple cout to check which discount was reached, and it says Handled when limit is 100 and discount is: 15, returning total price: 105 as it should be, BUT THEN, it somehow goes through the countDiscount function once again and returns 120 , which is the price without the discount applied, how is this possible?所以这里发生的事情是,正如您在FixatedDiscount.cpp中看到的那样,我做了一个简单的cout来检查达到了哪个折扣,它说Handled when limit is 100 and discount is: 15, returning total price: 105应该是,但是,它以某种方式再次通过countDiscount function 并返回120 ,这是没有应用折扣的价格,这怎么可能? It does not go to the third discount, but somehow it goes through that function once more and returns 120, so my theory is that when it reached the second discount it returned me what I want which is 105 since a discount of 15 was applied, then it goes back to the first pointer which is the first discount, and since 120 is not more than 150 it does not apply the discount and returns me 120. Why doesn't it just return me what I want and stop?它没有 go 到第三个折扣,但不知何故,它再次通过 function 并返回 120,所以我的理论是,当它达到第二个折扣时,它返回了我想要的105 ,因为应用了 15 的折扣,然后它回到第一个指针,即第一个折扣,由于 120 不超过 150,它不应用折扣并返回 120。为什么它不只是返回我想要的并停止? Why does it go through that function once more possibly going back by the pointer and applying again the discount that was already checked and shouldn't be checked anymore.为什么它 go 通过 function 再次可能通过指针返回并再次应用已经检查且不应再检查的折扣。

int FixatedDiscount::countDiscount(Basket b) {
    int totalPrice = b.countPrice(); //this method just counts the value of the basket which for our example is 120
    if (totalPrice >= limit) {
        totalPrice -= discount;
        std::cout << "Handled when limit is " << limit << " and discount is: " << discount << " returning total price: " << totalPrice << std::endl;
    }
    else if (next != NULL) {
        next->countDiscount(b);
    }
    else {
        std::cout << "I am the last handler" << std::endl;
    }
    return totalPrice;
}

After calling the next->countDiscount(b);在调用next->countDiscount(b); , the function doesn't return, it returns totalPrice which is unmodified after the discount is applied. ,function 不返回,它返回应用折扣后未修改的totalPrice You should assign the return value here for that discount to take effect.您应该在此处分配返回值以使该折扣生效。

totalPrice = next->countDiscount(b); should return 105.应该返回 105。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM