boost function对象 (二)

2014-11-24 00:56:16 · 作者: · 浏览: 5
w ImplA(); }
static ImplA_Factory _implAFactory;
};
ImplA_Factory ImplA_Factory::_implAFactory;

//同理,ImplB的实现

class ImplB : public Interface
{
public:
virtual void print(int a) {
std::cout << "== B == a=" << a << std::endl;
}
};
//提供ImplB的类工厂
class ImplB_Factory : public Interface_Factory
{
public:
Interface * create() { return new ImplB(); }
static ImplB_Factory _implBFactory;
};
ImplB_Factory ImplB_Factory::_implBFactory;
如果你要使用它,就需要这些写
[cpp]
std::map factories;

int main()
{
factories["A"] = &ImplA_Factory::_implAFactory;
factories["B"] = &ImplB_Factory::_implBFactory;
.....
}

std::map factories;

int main()
{
factories["A"] = &ImplA_Factory::_implAFactory;
factories["B"] = &ImplB_Factory::_implBFactory;
.....
}
如果仔细观察下,就会发现,实际上,ImplA_Factory和ImplB_Factory的内容几乎都一样。但是却写了不少重复性的代码。factory就是解决该问题的。


factory的解决之道
使用boost::factory,是完全不需要定义Interface_Factory接口和对应的实现的,我们定义一个boost::function对象,替代Interface_Factory
[cpp]

typedef boost::function< I *() > I_factory; //替代Interface_Factory的定义

typedef boost::function< I *() > I_factory; //替代Interface_Factory的定义用boost::factory替代ImplA_Factory和ImplB_Factory:
[cpp]
std::map factories;
....

factories["A"] = boost::factory (); //等价于 &ImplA_Factory::_ImplAFactory;
factories["B"] = boost::factory (); //等价于 &ImplB_Factory::_ImplBFactory;

std::map factories;
....

factories["A"] = boost::factory (); //等价于 &ImplA_Factory::_ImplAFactory;
factories["B"] = boost::factory (); //等价于 &ImplB_Factory::_ImplBFactory;

在使用的时候,与普通方法丝毫不差,如
[cpp]
void run_interface(const char* name)
{
I_factory factory = factories[name];
if(!factory)
{
std::cout<<"factory " << name << " is not exist" << std::endl;
return;
}
I *i = factory();
i->print(100);
delete i;
}

void run_interface(const char* name)
{
I_factory factory = factories[name];
if(!factory)
{
std::cout<<"factory " << name << " is not exist" << std::endl;
return;
}
I *i = factory();
i->print(100);
delete i;
}
通过判断factory的函数是否为空,就可以知道对应的类实现是否存在。我们可以这样简单的使用
[cpp]
run_interface("A");
run_interface("B");
run_interface("C");

run_interface("A");
run_interface("B");
run_interface("C");由于"C"对象不存在,因此,将打印 "factory C is not exist"的信息。


OverloadedFunction
考虑下面的代码
[cpp]
const std::string& identity_s(const std::string& x) // Function (as pointer).
{ return x; }

int identity_i_impl(int x) { return x; }
int (&identity_i)(int) = identity_i_impl; // Function reference.

double identity_d_impl(double x) { return x; }
boost::function identity_d = identity_d_impl; // Functor.

const std::string& identity_s(const std::string& x) // Function (as pointer).
{ return x; }

int identity_i_impl(int x) { return x; }
int (&identity_i)(int) = identity_i_impl; // Function reference.

double identity_d_impl(double x) { return x; }
boost::function identity_d = identity_d_impl; // Functor.
在调用他们的时候,必须使用各自的函数名:identity_i, indentity_s, indentity_d; 例如
[cpp]
BOOST_TEST(identity_s("abc") == "abc");
BOOST_TEST(identity_i(123) == 123);
BOOST_TEST(identity_d(1.23) == 1.23);

BOOST_TEST(identity_s("abc") == "abc");
BOOST_TEST(identity_i(123) == 123);
BOOST_TEST(identity_d(1.23) == 1.23);
但是,使用OverlaodedFunction,就可以使用统一的名字identity来调用了:
[cpp]
boost::overloaded_function<
const std::string& (const std::string&)
, int (int)
, double (double)
> identity(identity_s, identity_i, identity_d)