Juan
Juan

Reputation: 2103

Strategy Pattern C++

I want implement the strategy pattern in C++ but I have a doubt. Alwyas the strategy patterns examples are than follow code (in C#). I want modify the client, i.e MainClass, such that choose the concrete strategy will be dynamic way. For example, passing the strategy name by the args[] parameters of the main method. How I will be able to implement this without modify the properties of this pattern?.

namespace StrategyPatterns
{ 
  // Interface definition for a Sort algorithm
  public interface ISort
  {
  void Sort(List<string> list)
  }

  // QuickSort implementation
  public class CQuickSorter : ISort
  {
    void Sort(List<string> list)
    {
      // Here will come the actual imp
    }
  }

   // BubbleSort
  public class CBubbleSort : ISort
  {
    void Sort(List<string> list)
    {
      // The actual imp of the sort
    }
  }

  public class Context
  {
   private ISort sorter;

   public Context(ISort sorter)
   {
     // We pass the context the strategy to use
     this.sorter = sorter;
   }

public ISort Sorter
 {
  get{return sorter;)
 }
}

public class MainClass
{
    static void Main()
     {
       List<string> myList = new List<string>();

       myList.Add("Hello world");
       myList.Add("Another item");

       Contexto cn = new Contexto(new CQuickSorter());
       cn.Sorter.Sort(myList);
       cn = new Contexto(new CBubbleSort());
       cn.Sorter.Sort(myList);
    }
  }
}

Upvotes: 2

Views: 2325

Answers (2)

odinthenerd
odinthenerd

Reputation: 5552

I would give the context class a templated factory function setSorter and handle the entire lifetime of the sorter objects internally.

class Interface {  //this class and all sorting clases could be templated to be able to deal with sorting lists of different data types
    std::unique_ptr<ISort> sorter_;
public:
    Interface():sorter_(new CQuickSorter()){ //CQuickSorter is the default sorter
    }
    template<typename T>
    setSorter(){    //one could also use perfect forwarding to pass arguments to T's constructor
        sorter_.reset(new T());
    }
    void sort(std::list<string> &list){
        sorter_->sort(list); 
    }
};

int main(){
    std::list<int> li;
    Interface cn;
    cn.sort(li);  //using a default sort
    cn.setSorter<CBubbleSort>();
    cn.sort(li);  //using bubble sort
}

Upvotes: 0

Karthik T
Karthik T

Reputation: 31952

We do not have reflection in C++, that is the concept you need to get this to work right.. The alternative that I can think of, is to make a factory method as below..

ISort* CreateSorter(SortType type)
{
    switch (type){
    case QUICK_SORT: return new CQuickSorter();
    ...
    }
}

I use an enum for cleaner code, but you can change that into a string, as long as you are able to understand my basic point.

Upvotes: 1

Related Questions