1) Персональные настройки, но я бы изменил порядок параметров шаблона и по умолчанию использовал бы Ключ к std :: string (если это то, что вы будете использовать чаще всего)
template <typename Key, typename T> class Multiton { ... }
Тогда вы можете сделать это:
class Foo : public Multiton<Foo> {};
class Bar : public Multiton<Bar,int> {};
Что мне кажется более приятным.
2) Кроме того, если вы никогда не передаете указатели / ссылки на Multitron (что не нарушает шаблон), вам не нужен виртуальный деструктор в классе.
3) Если вы используете более умный контейнер для своих T * s, вы можете избежать вызова Foo :: destroy ().
Нечто подобное std::map<Key,boost::shared_ptr<T> >
уничтожит все объекты, когда будет уничтожен статический экземпляр. (Хотя, если вы заботитесь о порядке уничтожения, вам нужно что-то более умное - вы можете адаптировать что-то из существующих одноэлементных решений, таких как синглтоны фениксов и т. Д.)
4) Вы можете изменить итераторы на const_iterators.
5) Уничтожить, вероятно, следует очистить карту, чтобы предотвратить случайный доступ к недопустимой памяти после вызова уничтожения. Или, если вы хотите защититься от этого, вы должны выбросить исключение.
Foo* foo2 = Foo::getPtr("foobar");
Foo::destroy();
Foo::getPtr("foobar")->doSomething(); // BANG
6) Если вы не используете полиморфный T, то вы можете использовать std :: map, и ваш код будет выглядеть следующим образом ...
template <typename Key, typename T> class Multiton
{
public:
//Can probably get rid of this guy as maps destructor will do the right thing
static void destroy()
{
instances.clear();
}
static T& getRef(const Key& key)
{
return instances[key];
}
static T* getPtr(const Key& key)
{
return &instances[key];
}
protected:
Multiton() {}
virtual ~Multiton() {}
private:
Multiton(const Multiton&) {}
Multiton& operator= (const Multiton&) { return *this; }
static std::map<Key, T> instances;
};
Это все, что я могу думать сейчас.