Как лучше управлять экземплярами классов внутри фабрики? - PullRequest
0 голосов
/ 07 марта 2012

У меня проблема с "дизайном" в проекте 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 указатели в CcyPairclass.

Есть ли у вас лучший способ реализовать такой «шаблон», который гарантирует, что если два экземпляра класса (здесь класс Currency) имеют одинаковые атрибуты, то на самом деле это тот же экземпляр (та же основная ссылка)?

Ответы [ 2 ]

3 голосов
/ 07 марта 2012

То, что вы ищете, это шаблон Flyweight. Читать http://en.wikipedia.org/wiki/Flyweight_pattern

Кстати, с навесным весом вы также можете связать состояние, но вам придется отфильтровать это состояние в отдельный класс.

1 голос
/ 07 марта 2012

Я знаю, что вы сказали, что не хотите держать указатели на объекты 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;
      };
...