在工厂中管理类实例的更好方法是什么?

时间:2012-03-06 20:58:15

标签: c++ design-patterns factory

我在C ++项目中遇到了“设计”问题。

我有一个名为Currency的课程(可以是"USD""EUR",依此类推......并获得了一些方法) 在项目中到处都有这个类new-ed的许多实例,但是只能有一堆不同的货币(~100)。

所以我写了一个方法,在第一次询问时分配Currency,否则返回现有的Currency

    class Currency 
    {
    public:
      typedef std::map<std::string, Currency*> CurrencyMap_t;
    public:
      static CurrencyMap_t _currencies;

    public:
      static const Currency& getCcy(const std::string& name)
      {
        CurrencyMap_t::const_iterator it(_currencies.find(name));

        if (it == _currencies.end())
          it = _currencies.insert(std::make_pair(name, new Currency(name))).first;

        return *(it->second);
      }

    private:
      // can't instantiate from outside
      Currency();
      Currency(const Currency& other);
    private:
      // private ctor
      explicit Currency(const std::string& name) {... }
    };

所以,现在,我只有一个不同Currency的实例。

但是,我不能再有一个持有Currency成员的类,因为默认构造函数没有定义:

    class CcyPair
    {
    public:
      CcyPair(const Currency& ccy1, const Currency& ccy2) {}
    private:
      Currency _ccy1; // won't compile because "no default-constructor available"
      Currency _ccy2;
    };

我不想在Currency课程中持有CcyPair个指针。

你有更好的方法来实现这样一个“模式”,确保如果一个类的两个实例(这里是Currency类)具有相同的属性,那么它实际上是相同的< / strong>实例(相同的基础参考)?

2 个答案:

答案 0 :(得分:3)

您正在寻找的是Flyweight模式。阅读http://en.wikipedia.org/wiki/Flyweight_pattern

BTW与flyweight你也可以有一个状态关联,但必须将该状态过滤到一个单独的类。

答案 1 :(得分:1)

我知道你说你不想持有指向Currency对象的指针,但是你对拿到引用有什么看法呢?我不确定你是否想要避免使用指针,这样你就不会受到很多针对NULL的检查或者你有其他原因的负担。以下是使用引用的CcyPair示例:

  class CcyPair
      {
      public:
        CcyPair(const Currency& ccy1, const Currency& ccy2) 
          : _ccy1(ccy1), _ccy2(ccy2) {}

        CcyPair(const std::string& ccyName1, const std::string& ccyName2) 
          : _ccy1(Currency::getCcy(ccyName1)), _ccy2(Currency::getCcy(ccyName2)) {}

      private:
        // need to make these const since getCcy returns const 
        // you could also change the signature of getCcy to return non-const
        const Currency & _ccy1;
        const Currency & _ccy2;
      };