Poco::DynamicFactory

Poco::DynamicFactory を紹介します。

Poco::DynamicFactory は、クラス名からそのオブジェクトを作る Factory です。

DynamicFactoryTest.cpp

・Shape を継承した TriangleShape, RectangleShape, OvalShape クラスを定義。
・上記 3 者をテンプレート関数 RegisterClass() で再帰的に shapeFactory に登録。
・各 Shape のインスタンスポインタを Poco::SharedPtr に渡し、参照カウンタによるライフタイム管理。
・shapeFactory.createInstance() にクラス名を渡してオブジェクトを生成。
・draw() を呼んで、各クラスの動作を確認。

#include <Poco/DynamicFactory.h>
#include <Poco/TypeList.h>
#include <Poco/SharedPtr.h>
 
#include <string>
 
#include "ScopedLogMessage.h"
#include "PrepareConsoleLogger.h"
 
enum EShapeType
{
	eTriangle = 0
,	eRectangle
,	eOval
,	eNumShapes
};
 
const std::string kShapeNames[] =
{
	"Triangle"
,	"Rectangle"
,	"Oval"
};
 
class Shape
{
public:
	Shape() :
		m_pMsg(NULL)
	{
	}
 
	virtual ~Shape()
	{
	}
 
	void setScopedLogMessage(ScopedLogMessage& msg)
	{
		m_pMsg = &msg;
	}
 
	virtual void draw(void) = 0;
 
protected:
	void draw(const std::string& str)
	{
		if(m_pMsg)
		{
			m_pMsg->Message(" " + str);
		}
	}
 
private:
	ScopedLogMessage* m_pMsg;
};
 
class TriangleShape : public Shape
{
public:
	void draw(void)
	{
		Shape::draw(std::string("Triangle"));
	}
};
 
class RectangleShape : public Shape
{
public:
	void draw(void)
	{
		Shape::draw(std::string("Rectangle"));
	}
};
 
class OvalShape : public Shape
{
public:
	void draw(void)
	{
		Shape::draw(std::string("Oval"));
	}
};
 
typedef Poco::TypeListType<
	TriangleShape
,	RectangleShape
,	OvalShape
>::HeadType ShapeTypeList;
 
template<EShapeType N>
void RegisterClass(Poco::DynamicFactory<Shape>& shapeFactory)
{
	typedef typename Poco::TypeGetter<N, ShapeTypeList>::HeadType	ShapeType;
	shapeFactory.registerClass<ShapeType>(kShapeNames[N]);
	RegisterClass<static_cast<EShapeType>(N+1)>(shapeFactory);	// recursive call
}
 
template<>
void RegisterClass<eOval>(Poco::DynamicFactory<Shape>& shapeFactory)
{
	typedef Poco::TypeGetter<eOval, ShapeTypeList>::HeadType	ShapeType;
	shapeFactory.registerClass<ShapeType>(kShapeNames[eOval]);
}
 
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);
 
	ScopedLogMessage msg("DynamicFactoryTest ", "start", "end");
 
	Poco::DynamicFactory<Shape> shapeFactory;
 
	RegisterClass<eTriangle>(shapeFactory);	// recursive register
 
	Poco::SharedPtr<Shape> shapes[eNumShapes];
	for(std::size_t i=0; i<eNumShapes; ++i)
	{
		shapes[i] = Poco::SharedPtr<Shape>(shapeFactory.createInstance(kShapeNames[i]));
		shapes[i]->setScopedLogMessage(msg);
	}
 
	for(std::size_t i=0; i<eNumShapes; ++i)
	{
		shapes[i]->draw();
	}
 
	return 0;
}

Results of execution

[0] DynamicFactoryTest start
[0]  Triangle
[0]  Rectangle
[0]  Oval
[0] DynamicFactoryTest end

Downloads

ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年7月7日からのダウンロード数:774

Subversion

・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。

Reference

http://pocoproject.org にある MemoryManagement のプレセンテーション。(PDF)

Powered by POCO Copyright © 2010 Round Square Inc. All rights reserved.


Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>