概述
当需要根据不同的情况创建多个同一基类的不同子类时,可以采用工厂模式。
/**
* @class Factory
* @brief Implements a Factory design pattern with Register and Create methods
* * The objects created by this factory all implement the same interface
* (namely, AbstractProduct). This design pattern is useful in settings where
* multiple implementations of an interface are available, and one wishes to
* defer the choice of the implementation in use.
* * @param IdentifierType Type used for identifying the registered classes,
* typically std::string.
* @param AbstractProduct The interface implemented by the registered classes
* @param ProductCreator Function returning a pointer to an instance of
* the registered class
* @param MapContainer Internal implementation of the function mapping
* IdentifierType to ProductCreator, by default std::unordered_map
*/
template <typename IdentifierType, class AbstractProduct,
class ProductCreator = AbstractProduct *(*)(),
class MapContainer = std::map<IdentifierType, ProductCreator>>
class Factory {
public:
/**
* @brief Registers the class given by the creator function, linking it to id.
* Registration must happen prior to calling CreateObject.
* @param id Identifier of the class being registered
* @param creator Function returning a pointer to an instance of
* the registered class
* @return True iff the key id is still available
*/
bool Register(const IdentifierType &id, ProductCreator creator) {
return producers_.insert(std::make_pair(id, creator)).second;
}
/**
* @brief Unregisters the class with the given identifier
* @param id The identifier of the class to be unregistered
*/
bool Unregister(const IdentifierType &id) {
return producers_.erase(id) == 1;
}
void Clear() { producers_.clear(); }
bool Empty() const { return producers_.empty(); }
/**
* @brief Creates and transfers membership of an object of type matching id.
* Need to register id before CreateObject is called. May return NULL
* silently.
* @param id The identifier of the class we which to instantiate
* @param args the object construction arguments
*/
template <typename... Args>
std::unique_ptr<AbstractProduct> CreateObjectOrNull(const IdentifierType &id,
Args &&... args) {
auto id_iter = producers_.find(id);
if (id_iter != producers_.end()) {
return std::unique_ptr<AbstractProduct>(
(id_iter->second)(std::forward<Args>(args)...));
}
return nullptr;
}
/**
* @brief Creates and transfers membership of an object of type matching id.
* Need to register id before CreateObject is called.
* @param id The identifier of the class we which to instantiate
* @param args the object construction arguments
*/
template <typename... Args>
std::unique_ptr<AbstractProduct> CreateObject(const IdentifierType &id,
Args &&... args) {
auto result = CreateObjectOrNull(id, std::forward<Args>(args)...);
PUB_E_IF(!result, "Factory could not create Object of type : " << id);
return result;
}
private:
MapContainer producers_;
};
在上述类模板中类型定义如下:
- IdentifierType代表类型标识,根据该类型标识来决定创建哪个AbstractProduct。
- AbstractProduct代表某个抽象基类,所有通过工厂生成的类都是这个基类的子类。
- ProductCreator代表一个函数指针,该指针指向一个函数,这个函数返回一个指向抽象基类对象的指针,可以用来产生子类的对象指针。(函数指针:返回值类型 ( * 指针变量名) ([形参列表]))
- MapContainer代表一个映射关系,将类型标识映射到ProductCreator,这样就可以根据类型标识来决定用哪个ProductCreator函数指针去创建子类。
在使用时,主要需要使用Register和CreateObject两个方法:
- Register用于创建类型标识和子类创建器之间的映射关系,这样后面就可以根据类型标识来创建对应的子类了。
- CreateObject用于将创建子类所需的参数传递给子类,并返回一个指向子类对象的指针。
最后
以上就是无辜唇彩为你收集整理的C++类模板实现工厂模式的全部内容,希望文章能够帮你解决C++类模板实现工厂模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复