среда, 21 августа 2013 г.

shared_ptr factory

tmp-12112Ddy
/** Многие до сих пор пишут свои фабрики объектов, хотя есть boost::shared_ptr и boost::factory
    При чём есть возможность передавать аргументы при создании
    объектов. Например, есть система полиморфных объектов: */

#include <map>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/assign.hpp>
#include <boost/function.hpp>
#include <boost/functional/factory.hpp>

#define LOG(WHAT) std::cout << WHAT << std::endl

struct A
{
  virtual void func() = 0;
protected:
  ~A() {}
};

struct B: A
{
  B(int a): a(a) {}
  void func() { LOG("it's B"); }
  int a;
};

struct C: A
{
  C(int a): a(a) {}
  void func() { LOG("it's C"); }
  int a;
};

/** Объекты при создании принимают один аргумент: int.  Давайте
    создадим фабрику, которая будет создавать объекты, помещённые в
    смарт поинтер boost::shared_ptr. Для создания фабрики достаточно
    описать следующее: */
typedef boost::function<boost::shared_ptr<A>(int)> factory_t;

/** Связываем фабрики конкретных типов "B" и "C" с идентификаторами:
    "class_B" и "class_C": */
std::map<std::string, factory_t> fact = boost::assign::map_list_of
    ("class_B", factory_t(boost::factory<boost::shared_ptr<B> >()))
    ("class_C", factory_t(boost::factory<boost::shared_ptr<C> >()))
    ;

/** Использование: Создаём объект по идентификатору "class_B" и
    передаём аргумент, например, 33. */
boost::shared_ptr<A> a = fact["class_B"](33);
a->func();

/** Можно добавлять "фабрики по умолчанию", более подробно в доках
    http://www.boost.org/doc/libs/1_51_0/libs/functional/factory/doc/html/index.html */
 

Комментариев нет:

Отправить комментарий