Я пытаюсь написать базовый класс и набор из N производных классов, где каждый каждый производный класс имеет свой уникальный идентификатор, вот простая, «ручная» реализация:
struct Base {
static int id_ = 0;
};
struct Derived1 : public Base {
static int id_ = 1;
};
struct Derived2 : public Base {
static int id_ = 2;
};
Проблема в том, что если я хочу продолжить добавление производных классов, я должен подсчитать количество уже существующих производных классов.
Все также усложняется, потому что я хочу использовать битовый набор для представления уникального идентификатора. Если уникальный идентификатор каждого производного класса в основном представляет собой просто отдельный бит (из набора битов общей длины), установленный в 1, это позволяет очень легко выполнять двоичные операции AND / OR / XOR / etc для групп производных классов.
Ниже приведена неполная и неправильная реализация того, что я хочу
//Let DCOUNT be the number of derived classes, Ideally I shouldnt have to ever
//know/think about what it evaluates too, it should be automatic.
//But that is second priority, I would be willing to #define this to
//some 'large' value, and not worry about it.
struct Base {
static std::bitset<DCOUNT> id_ = generateUniqueID(); // "00000"};
struct Derived1 {
static std::bitset<DCOUNT> id_ = generateUniqueID(); // "00001"};
struct Derived2 {
static std::bitset<DCOUNT> id_ = generateUniqueID(); // "00010"};
Каков наилучший способ реализовать это? (или что-то подобное)
Как насчет чего-то простого, такого как семейство функций (шаблон), которое генерирует и сохраняет идентификатор для каждого типа, например так:
template<typename T>
static std::bitset<DCOUNT> getId()
{
static std::bitset<DCOUNT> bitset;
static bool bitsetCreated = false;
if ( false == bitsetCreated )
{
bitset = generateUniqueID();
bitsetCreated = true;
}
return bitset;
}
После этого вы можете получить следующие идентификаторы: getId < YourType> ();
Они генерируются во время выполнения, поэтому нет проблем с generateUniqueID ();
Это RTTI.
Вы не можете инициализировать статический член с помощью внешней функции, вы получите ошибки компилятора, такие как
'generateUniqueID()' cannot appear in a constant-expression
или же
ISO C++ forbids in-class initialization of non-const static member ‘id_’
Я думаю, что все, что вы можете сделать, это инициализировать id_
значения от руки.
У вас также есть альтернатива, чтобы узнать типы ваших классов: используйте typeid
функция, как в
if (typeid(myInstance) == typeid(Derived1))
do_something();