C++ 如何将参数传递给工厂元素构造函数?
我有一个类树,我想存储在织物中。我看到了如何为具有空构造函数或预定义构造函数的元素实现结构,但我看不到如何使不具有预定义构造函数参数的元素得以使用。我们也这么说。我们的工厂是这样的: 工厂。水电站:C++ 如何将参数传递给工厂元素构造函数?,c++,boost,C++,Boost,我有一个类树,我想存储在织物中。我看到了如何为具有空构造函数或预定义构造函数的元素实现结构,但我看不到如何使不具有预定义构造函数参数的元素得以使用。我们也这么说。我们的工厂是这样的: 工厂。水电站: #include <unordered_map> #include <string> template<class BaseType, class BaseTypeCode> class Factory { public: typedef BaseTyp
#include <unordered_map>
#include <string>
template<class BaseType, class BaseTypeCode>
class Factory {
public:
typedef BaseType * (*base_creator_fn)();
typedef std::unordered_map<BaseTypeCode, base_creator_fn> registry_map;
static registry_map & registry() {
static registry_map impl;
return impl;
}
static BaseType * instantiate(BaseTypeCode const & name) {
auto it = registry().find(name);
return it == registry().end() ? nullptr : (it->second)();
}
virtual ~Factory() = default;
};
template<class BaseClass, class BaseTypeCode>
struct Registrar {
Registrar(BaseTypeCode name, Factory<BaseClass>::base_creator_fn func) {
Factory<BaseClass>::registry()[name] = func;
}
};
#include "Factory.hpp"
enum ExampleTypeCode { ExampleTypeCode_Simple = 1 };
class ExampleBase {
virtual ~ExampleBase(){}
};
class Example : public ExampleBase {
Example(int i) {}
virtual ~Example(){}
static Registrar<ExampleBase, ExampleTypeCode> registrar;
};
#include <boost/bind.hpp>
#include <boost/lambda.hpp>
#include "Example.hpp"
Registrar<Example, ExampleTypeCode> Example::registrar(ExampleTypeCode_Simple, boost::bind(boost::lambda::new_ptr<Example>, _firstVarArg));
示例。cpp:
#include <unordered_map>
#include <string>
template<class BaseType, class BaseTypeCode>
class Factory {
public:
typedef BaseType * (*base_creator_fn)();
typedef std::unordered_map<BaseTypeCode, base_creator_fn> registry_map;
static registry_map & registry() {
static registry_map impl;
return impl;
}
static BaseType * instantiate(BaseTypeCode const & name) {
auto it = registry().find(name);
return it == registry().end() ? nullptr : (it->second)();
}
virtual ~Factory() = default;
};
template<class BaseClass, class BaseTypeCode>
struct Registrar {
Registrar(BaseTypeCode name, Factory<BaseClass>::base_creator_fn func) {
Factory<BaseClass>::registry()[name] = func;
}
};
#include "Factory.hpp"
enum ExampleTypeCode { ExampleTypeCode_Simple = 1 };
class ExampleBase {
virtual ~ExampleBase(){}
};
class Example : public ExampleBase {
Example(int i) {}
virtual ~Example(){}
static Registrar<ExampleBase, ExampleTypeCode> registrar;
};
#include <boost/bind.hpp>
#include <boost/lambda.hpp>
#include "Example.hpp"
Registrar<Example, ExampleTypeCode> Example::registrar(ExampleTypeCode_Simple, boost::bind(boost::lambda::new_ptr<Example>, _firstVarArg));
我的主要编译目标是最新的GCC和Visual Studio 2012以及最新的service pack,因此C++11子集还非常有限。您可以将工厂与构建器结合起来,以获得所需的行为。构建器将保存这些参数
template<class BaseType, class BaseTypeCode, class BaseTypeBuilder>
class Factory {
public:
typedef BaseType * (*base_creator_fn)(BaseTypeBuilder const &);
//...
static BaseType * instantiate(BaseTypeCode const & name,
BaseTypeBuilder const & builder
= BaseTypeBuilder()) {
auto it = registry().find(name);
return it == registry().end() ? nullptr : (it->second)(builder);
}
virtual ~Factory() = default;
};
可变模板可以帮助这里。我使用了
void*
作为第二种类型的registry\u map
,这样我们就可以在注册表中存储任何类型的函数。下面是一段演示基本思想的简短代码:
class Base
{
public:
typedef std::unordered_map<std::string, void*> registry_map;
virtual ~Base() = default;
static registry_map & registry()
{
static registry_map impl;
return impl;
}
template<typename ...T>
static Base * instantiate(std::string const & name, T&&...args)
{
auto it = registry().find(name);
if ( it == registry().end()) return 0;
typedef Base* (*create_type)(T...);
auto create_fun = reinterpret_cast<create_type>(it->second);
return create_fun(args...);
}
virtual void f() = 0;
};
struct Registrar
{
template<typename F>
Registrar(std::string name, F func)
{
Base::registry()[name] = reinterpret_cast<void*>(func);
}
};
希望有帮助。:-) 我想你必须使用某种类型的类型擦除。你能用C++11吗?顺便说一句,
示例
不是从ExampleBase
派生出来的。而且,Example.cpp
文件中似乎有输入错误。请先解决这些问题。@Nswaz:修复了一些打字错误,VS2012主要问题。。。所以一些C++11还不是全部。你好,回答,谢谢你的想法!您能说明在C++03/C中如何使用变长参数进行变长吗?@DuckQueen:要支持C++03中的变长参数,您需要在代码中添加重载函数模板。只要看看当前的代码是如何工作的,这将让您了解如何在C++03中完成它。
DerivedExample
AnotherExample. a = 10, b = Mahfuza