This is a sample implementation of Strategy Pattern in C++:
ConcreteStrategy.h
class ConcreteStrategy {
public:
ConcreteStrategy();
~ConcreteStrategy();
const OtherObject* doSomething(const OtherObject &obj);
};
ConcreteStrategy.cpp
#include "ConcreteStrategy.h"
ConcreteStrategy::ConcreteStrategy() { // etc. }
ConcreteStrategy::~ConcreteStrategy() { // etc. }
const OtherObject* ConcreteStrategy::doSomething(const OtherObject &obj) { // etc. }
MyContext.h
template <class Strategy> class MyContext {
public:
MyContext();
~MyContext();
const OtherObject* doAlgorithm(const OtherObject &obj);
private:
Strategy* _the_strategy;
};
MyContext.cpp
#include "MyContext.h"
template <typename Strategy>
MyContext<Strategy>::MyContext() {
_the_strategy = new Strategy;
}
template <typename Strategy>
MyContext<Strategy>::~MyContext() {
delete _the_strategy;
}
template <typename Strategy>
const OtherObject* MyContext<Strategy>::doAlgorithm(const OtherObject &obj) {
obj = _the_strategy(obj);
// do other.
return obj;
}
main.cpp
#include "MyContext.h"
#include "ConcreteStrategy.h"
#include "OtherPrivateLib.h"
int main(int argc,char **argv) {
OtherObject* obj = new OtherObject;
MyContext<ConcreteStrategy>* aContext = new MyContext<ConcreteStrategy>;
obj = aContext.doAlgorithm(obj);
// etc.
delete aContext;
delete obj;
return 0;
}
Is this implementation right? It's my first approach with template in C++ and I've some doubt, specially about construction and destruction of template object (Strategy) inside the context (MyContext).
UPDATE: I've this error at compile-time:
undefined reference to `MyContext<Strategy>::MyContext()'
First, the class template implementations should go in the header file or in a file included by the header, not in a .cpp file to be compiled. The compiler needs to see the template code in order to create the MyContext<ConcreteStrategy>
required by main
. This is the cause of the compiler error.
Second, and unrelated to templates, you have many uses of dynamically allocated objects for no apparent reason. I would change doSomething
and doAlgorithm
to return by value, for example
OtherObject doSomething(const OtherObject &obj);
and remove all uses of new
from the main, for example:
int main(int argc,char **argv) {
OtherObject obj;
MyContext<ConcreteStrategy> aContext;
obj = aContext.doAlgorithm(obj);
return 0;
}
If you really must use dynamically allocated objects, then I suggest using smart pointers, particularly C++11's std::unique_ptr.