In order to strengthen my English writing, I will try to write blog in English.
I have read the book
Api Design For C++
recently, and I must say that it is a masterpiece.
There is a section to introduce the Factory Pattern, I think it is the best practical example for this pattern which I have read.
So I code it according the example, made some modification and added some annotation, then now share with you guys.
renderer.h
#include <iostream>
#include <string>
class IRenderer
{
public:
virtual void Render()=0;
virtual ~IRenderer()
{
std::cout<< "delete IRenderer object."<<std::endl;
}
};
class UserRenderer:public IRenderer
{
public:
~UserRenderer()
{
std::cout<< "delete UserRenderer object."<<std::endl;
}
bool LoadScene(const std::string &filename)
{
return true;
}
void SetViewportSize(int w, int h) {}
void SetCameraPosition(double x, double y, double z) {}
void SetLookAt(double x, double y, double z) {}
void Render()
{
std::cout << "User Render" << std::endl;
}
static IRenderer* Create()
{
return new UserRenderer(); //Pay attention: this method must be static.
}
};
rendererfactory.h
#include "renderer.h"
#include <string>
#include <map>
class RendererFactory
{
public:
typedef IRenderer* (*CreateCallback)();
static void RegisterRenderer(const std::string& type, CreateCallback cb);
static void UnregisterRender(const std::string& type);
static IRenderer* CreateRenderer(const std::string& type);
private:
typedef std::map<std::string, CreateCallback> CallbackMap;
static CallbackMap mRenderers;
};
rendererfactory.cpp
#include "rendererfactory.h"
RendererFactory::CallbackMap RendererFactory::mRenderers;
void RendererFactory::RegisterRenderer(const std::string &type, RendererFactory::CreateCallback cb)
{
mRenderers[type] = cb;
}
void RendererFactory::UnregisterRender(const std::string &type)
{
mRenderers.erase(type);
}
IRenderer* RendererFactory::CreateRenderer(const std::string &type)
{
CallbackMap::iterator it = mRenderers.find(type);
if(it!=mRenderers.end())
{
return (it->second)();
}
return NULL;
}
mainFile.cpp
#include <iostream>
#include "rendererfactory.h"
using namespace std;
int main()
{
//Register a new renderer
RendererFactory::RegisterRenderer("user", UserRenderer::Create);
//create an instance of our new renderer
IRenderer* render = RendererFactory::CreateRenderer("user");
render->Render();
delete render; //Remember to release the resources on heap.
getchar()
return 0;
}
Reference:
Api Design For C++, Martin Reddy,
Section: 3.3.3 Extensible Factory Example