Given a typical strategy template
class Strategy { public: virtual int execute() const = 0; } class StrategyA : public Strategy { public: int execute() const override; } class StrategyB : public Strategy { public: int execute() const override; }
I believe that the pre-C ++ 11 method for implementing the context class would be similar to
class ContextRaw { public: ContextRaw(Strategy* the_strategy); ~ContextRaw();
For me in this design it is not clear whether Context take responsibility for the Strategy , and if it does not have clear documentation indicating otherwise, bad things can happen if they are
void trouble() { StrategyA a_concrete_strategy; ContextRaw a_context(&a_concrete_strategy); // Oops, Context may try to delete stack variable } void more_trouble() { Strategy* a_concrete_strategy = new StrategyA; ContextRaw* a_context = new ContextRaw(a_concrete_strategy); ContextRaw* another_context = new ContextRaw(a_concrete_strategy); delete a_context; std::cout << another_context.execute() << std::endl; // Oops, the_strategy is deleted }
In the light of safe pointers, should it now be preferable to introduce a safe pointer and have Context take charge of Strategy ?
class ContextUnique { public: ContextUnique() = delete; ContextUnique(std::unique_ptr<Strategy> the_strategy); ~ContextUnique(); int execute() const; private: std::unique_ptr<Strategy> the_strategy_; }
or if Strategy can be divided between different Context ?
class ContextShared { public: ContextShared() = delete; ContextShared(std::shared_ptr<Strategy> the_strategy); ~ContextShared(); int execute() const; private: std::shared_ptr<Strategy> the_strategy_; }
This design, of course, introduces problems of its own, in particular, only dynamically allocated Strategy can be entered into Context .