John Humphreys
John Humphreys

Reputation: 39294

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 hierarchy 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 :)

Upvotes: 27

Views: 11667

Answers (6)

Ajay
Ajay

Reputation: 18431

IMO, strategy 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.

Upvotes: 3

mehmet riza oz
mehmet riza oz

Reputation: 559

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;
}

Upvotes: 0

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81694

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.

Upvotes: 9

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361492

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.

Upvotes: 20

fredoverflow
fredoverflow

Reputation: 263148

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.

Upvotes: 24

Alexandre C.
Alexandre C.

Reputation: 56956

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

Upvotes: 2

Related Questions