Всем привет!
Есть некоторая иерархия классов, в которой от одного базового наследуется ещё куча. Возникла такая проблема: надо добавить общую для всех экземпляров классов этой иерархии одну «общую» переменную.
Казалось бы, всё решается просто через статическую переменную-член в базовом классе, но теоретически в дальнейшем может возникнуть надобность в ещё некоторых классах-наследниках этого базового, для которых у этой переменной должно быть отдельное значение.
Поясню на простом примере: есть базовый класс для юнитов определенной игры, в котором роль «общей» переменной играет общее количество юнитов. Допустим, у нас есть юниты нескольких «семейств», и количество их должно подсчитываться для каждого «семейства» отдельно (т.е., например, n лодок и k вертолётов).
Я дошёл до следующего решения - сделать идентификацию «семейств» через enum, а базовый класс сделать шаблонным с шаблонным параметром - идентификатором семейства. Таким образом можно при наследовании указывать семейство и получать уникальный экземпляр переменной для каждого из семейств. Выглядит это всё примерно так:
#include <iostream>
#include <iomanip>
enum group {air, navy};
template <group gr>
class unit
{ static int _count;
public:
unit ()
{ ++unit<gr>::_count;
}
~unit ()
{ --unit<gr>::_count;
}
int count () const
{ return unit<gr>::_count;
}
};
template <group gr>
int unit<gr>::_count = 0;
class helicopter: public unit<air> {};
class fighter: public unit<air> {};
class boat: public unit<navy> {};
int main (int argc, char *argv[])
{ helicopter hh, h[3];
boat bb, b[7];
fighter f[2];
std::cout << "== The battlefield ==" << std::endl
<< std::setw (15) << "Air units: " << hh.count() << std::endl
<< std::setw (15) << "Navy units: " << bb.count() << std::endl;
return 0;
}
На выходе получим:
/home/dmatveev $ ./separate
== The battlefield ==
Air units: 6
Navy units: 8
Т.е. как бы работает... И тут собственно сам вопрос - насколько крив и костылен этот метод? Может есть другие, более правильные пути решения, или вообще это ошибка проектирования? Хотелось бы услышать мнение более опытных форумчан.
P.S. Извиняюсь за многобуков =)