I'm reasing about the best way to implement the strategy pattern in C++. Up to now, I've always used the standard way, where the context has a pointer to the base strategy class as follows:
class AbstractStrategy{
public:
virtual void exec() = 0;
}
class ConcreteStrategyA{
public:
void exec();
}
class ConcreteStrategyB{
public:
void exec();
}
class Context{
public:
Context(AbstractStrategy* strategy):strategy_(strategy){}
~Context(){
delete strategy;
}
void run(){
strategy->exec();
}
private:
AbstractStrategy* strategy_;
Since having pointers to objects can result in bad behavior, I was looking for a safer way to implement this pattern and I found this question where std::function
are proposed as a better way to handle this pattern.
Could someone please explain better how std::function
works, maybe with an example with the strategy pattern?
Note that single-method objects are isomorphic to functions, and strategies are just single-method objects.
So basically, you get rid of all your classes, and you just use std::function<void()>
instead:
class Context {
public:
template<typename F>
explicit Context(F strategy) : strategy(std::move(strategy)) { }
void run() { strategy(); }
private:
std::function<void()> strategy;
};
Then you can pass any callable to the constructor of Context
:
Context ctx([] { std::cout << "Hello, world!\n"; });
ctx.run();