开发者

C++ Strategy pattern

In the past, I have seen the strategy pattern explained as a mechanism which allows the user of a function/class to provide their own functionality for that function/class.

I had always been taught that the way to implement the pattern was by taking function pointers into your classes/functions and calling them internally, thus allowing the programmer to provide their own "strategy" which would be used internally by those functions and objects.

Looking around more recently, I see that the strategy pattern always seems to be explained/defined through the use of an inheritance hierarch开发者_开发知识库y like so:

Strategy pattern implementation

is this a difference of opinion/implementation, or is the function pointer passing not really a variation of the strategy pattern? I'm mostly interested so I don't confuse people when I comment or explain my code :)


You simply have to use inheritance in languages without function pointers (read: Java).

Personally, I would prefer std::function over raw function pointers, because it accepts a wider range of arguments and allows you to maintain state in the strategy object.

Also, if you already know the strategy at compile-time, you can even use templates and thus save both the space and runtime overhead of function pointers and std::function objects.


In my opinion, implementation of strategy pattern using function pointers is done in languages which don't have support for OOP (such as C).

In languages which support OOP, its better implemented using classes : inheritance, virtual functions (i.e runtime polymorphism), interface, and so on. Usually, this is runtime strategy pattern which means, you can change the behavior of the program just by switching to other strategy pattern, at runtime.

In C++, there is also a compile-time strategy pattern, commonly known as policy-based design.

In any case, classes can maintain states, while function pointers cannot. That is the biggest advantage in using classes.


Using function pointers to implement strategy is sort of a degenerate case of the inheritance based version. The essential kernel of the pattern is, as you know, being able to supply or modify a component of some process at runtime. That component can be a function, or it can be an object. If the strategy consists of several bits, an inheritance-based version is really nicer, as an object can package several methods together; if there's just one piece, then function pointers are pretty much as good.


Interface objects can have state, and therefore maintain member variables. Function pointers cannot.


IMO, starategy pattern can be implemented using:

  • Templates and compile-time constant expressions (Early-bound, may not be actually called as strategy-pattern).
  • Virtual function mechanism (Yes, by assigning different derived classes to a reference/pointer).
  • Function pointers
  • Pointer-to-members (methods) of a class.
  • Using std::function, and using lambdas.


This is a practical code for strategy pattern in c++. I hope pure virtual funcation usage (instead of interface in Java) is self explanatory.

#include <iostream>
#include <fstream>
#include <string.h>

using namespace std;

class Strategy;

class TestBed{
  public:
    TestBed(){
        myStrategy = NULL;
    }
    void setBehavior(int type);
    Strategy *myStrategy;
};

class Strategy{
  public:
    void performBehavior(){
       behave();
    }
  private:
    virtual void behave() = 0;
};

class behaviorOne: public Strategy{
  private:
    void behave(){
        cout << "left strategy" << endl;
    }
};

class behaviorTwo: public Strategy{
  private:
    void behave(){
        cout << "right strategy" << endl;
    }
};

class behaviorThree: public Strategy{
  private:
    void behave(){
        cout << "center strategy" << endl;
    }
};

void TestBed::setBehavior(int type){  
  delete myStrategy;
  if (type == 0)
    myStrategy = new behaviorOne();
  else if (type == 1)
    myStrategy = new behaviorTwo();
  else if (type == 2)
    myStrategy = new behaviorThree();
}

int main(){
  TestBed test;
  int answer;  
  while(1){
     cout << "Exit(other) Left(0) Right(1) Center(2): ";
     cin >> answer;
     if(answer > 2) break;
     test.setBehavior(answer);
     test.myStrategy->performBehavior();
  }   
  return 0;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜