سؤال

I'm trying to implement a Strategy design pattern in C++.

I have an abstract class with no non-abstract method called ICookingStrategy:

class ICookingStrategy
{
    public:
        virtual int cook() = 0;
};

From this abstract class inherit two child classes: fastCooking and slowCooking:

Child classes

class fastCooking : public ICookingStrategy
{
    public:
        int cook() { return 0; }
};

class slowCooking : public ICookingStrategy
{
    public:
        int cook() { return 0; }
};

Context class

The point is, I want another class to be populated by an object instanciating either fastCooking or slowCooking, indifferently. Which means, an object instantiating ICookingStrategy.

But my problem is: I can't find how I can populate this receiving class. I thought in the constructor's arguments, but when I try this, g++ gives me an error:

class CookingContext
{
    public:
        CookingContext (ICookingStrategy* cookingStrategy):cookingStrategy(cookingStrategy)
        {}

        int cook()
        {
            this->cookingStrategy.cook();
            return 0;
        }

    private:
        ICookingStrategy* cookingStrategy;
};

In main(), I want to do instantiate one of the two child classes, then populate CookingContext like this:

int main(void)
{
  ICookingStrategy* cookingStrategy;
  cookingStrategy = new fastCooking;

  CookingContext cooking(cookingStrategy);
  cooking.cook();

  return 0;
}

G++ error message on compilation is:

error: expected ‘)’ before ‘*’ token
CookingContext(ICookingStrategy* cookingMode):cookingMode(cookingMode)
                               ^

So my question is...

What is the best way to make CookingContext being populated by the strategy object, instantiating either child of ICookingStrategy?

(tried many different ones, and didn't manage to make it work)

هل كانت مفيدة؟

المحلول 2

Your constructor should take ownership of a caller-provided instance of one of the concrete cooking strategies, but needs to do so by pointer:

CookingContext(ICookingStrategy* cookingStrategy): cookingStrategy(cookingStrategy) {...}

ICookingStrategy* cookingStrategy;

int cook()
{
    return cookingStrategy->cook();
}

A destructor should be added to delete the cooking strategy:

~CookingContext() { delete cookingStrategy; }

نصائح أخرى

The run-time polymorphism works on references and pointers, not on objects. Here you are using a pass-by-value for an abstract class in the constructor. You cannot create an object of abstract class. That's why the compiler is complaining!

Answers by Simal Haneef and Tony D are correct.

The code should be like:

class CookingContext
{
public:
    CookingContext (ICookingStrategy* cookingStrategy):cookingStrategy(cookingStrategy)
    {
        cout <<< "CookingContext constructor has been called" <<< endl;
    }

    int cook()
    {
        cookingStrategy->cook();
        return 0;
    }

private:
    ICookingStrategy* cookingStrategy;
};
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top