![](/img/trans.png)
[英]Factory Pattern for Template Classes and Default Argument of New Type for Template Classes
[英]Instantiating classes by name with factory pattern
假设我有一个A, B, C, ...
类的列表A, B, C, ...
它们都继承自Base
。
我从类用户获取类名作为字符串,我想实例化正确的类并返回指向Base
的指针。 你会如何实现这个?
我想过使用带有类名作为键的哈希表,以及一个函数指针,该函数指向实例化右类并返回Base *
的函数。
但是,我想我可以在这里使用工厂模式并使其更容易,但我不能很好地记住它,所以我虽然我会寻求建议。
这是一个通用的工厂示例实现:
template<class Interface, class KeyT=std::string>
struct Factory {
typedef KeyT Key;
typedef std::auto_ptr<Interface> Type;
typedef Type (*Creator)();
bool define(Key const& key, Creator v) {
// Define key -> v relationship, return whether this is a new key.
return _registry.insert(typename Registry::value_type(key, v)).second;
}
Type create(Key const& key) {
typename Registry::const_iterator i = _registry.find(key);
if (i == _registry.end()) {
throw std::invalid_argument(std::string(__PRETTY_FUNCTION__) +
": key not registered");
}
else return i->second();
}
template<class Base, class Actual>
static
std::auto_ptr<Base> create_func() {
return std::auto_ptr<Base>(new Actual());
}
private:
typedef std::map<Key, Creator> Registry;
Registry _registry;
};
这并不意味着在每种情况下都是最好的,但它的目的是作为第一个近似和一个比手动实现所提到的函数类型更有用的默认值。 每个层次结构应该如何注册本身并不是Factory规定的,但是你可能会喜欢上面提到的方法 (它简单,清晰,非常有用,是的,这可以克服宏在这种情况下的固有问题)。
这是工厂的一个简单示例 :
struct Base {
typedef ::Factory<Base> Factory;
virtual ~Base() {}
virtual int answer() const = 0;
static Factory::Type create(Factory::Key const& name) {
return _factory.create(name);
}
template<class Derived>
static void define(Factory::Key const& name) {
bool new_key = _factory.define(name,
&Factory::template create_func<Base, Derived>);
if (not new_key) {
throw std::logic_error(std::string(__PRETTY_FUNCTION__) +
": name already registered");
}
}
private:
static Factory _factory;
};
Base::Factory Base::_factory;
struct A : Base {
virtual int answer() const { return 42; }
};
int main() {
Base::define<A>("A");
assert(Base::create("A")->answer() == 42);
return 0;
}
在许多领域中最快捷但非常有用的方式就像是
Base* MyFactoryMethod( const std::string& sClass ) const
{
if( sClass == "A" )
return CreateNewA();
else if( sClass == "B" )
return new CreateClassB();
//....
return 0;
}
A* CreateClassA() const
{
return new A();
}
您还可以查看Boost类工厂实现。
这是一个使用Boost工厂方法和类注册的简单示例:
typedef boost::function<Parent*()> factory;
// ...
std::map<std::string, factory> factories;
// Register derived classes
factories["Child1"] = boost::factory<Child1*>();
factories["Child2"] = boost::factory<Child2*>();
// ...
// Instantiate chosen derived class
auto_ptr<Parent> pChild = auto_ptr<Parent>(factories["Child1"]());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.