我是靠谱客的博主 无辜唇彩,最近开发中收集的这篇文章主要介绍C++类模板实现工厂模式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

当需要根据不同的情况创建多个同一基类的不同子类时,可以采用工厂模式。

/**
 * @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++类模板实现工厂模式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部