Числовой уникальный идентификатор класса через typeid

Оператор typeid в C++ возвращает объект класса std::type_info, который может дать его текстовое имя. Однако меня просто интересует получение уникального числового идентификатора для любого полиморфного класса. (уникально в рамках одного запуска программы - не обязательно между запусками)

На практике я мог бы просто разыменовать указатель и прочитать содержимое vptr, но это было бы не элегантно и не переносимо. Я предпочитаю портативный способ.

Могу ли я каким-то образом использовать оператор typeid, чтобы иметь «безопасный» числовой идентификатор для класса? Например, могу ли я рассчитывать на то, что адрес результирующей структуры std::type_info будет одинаковым для каждого вызова typeid данного класса? Или, может быть, сам указатель name()?


person Kos    schedule 19.04.2011    source источник
comment
Вы можете вычислить хэш имени typeid. Поскольку это строковый литерал, он также должен быть разрешен во время компиляции. По крайней мере, так говорит самоцвет, откуда я взял эту идею... у меня другой опыт. Для меня накладные расходы этого решения неприемлемо высоки. Но, конечно, он портативный, так что... да.   -  person Damon    schedule 19.04.2011
comment
Какую проблему вы на самом деле пытаетесь решить здесь?   -  person Mark B    schedule 19.04.2011
comment
Проблема в том, что я пытался сопротивляться приведению адреса объекта к void** и разыменовыванию его для vptr. :D А если серьезно - что-то похожее на 2-мерную виртуальную таблицу.   -  person Kos    schedule 19.04.2011
comment
Адрес структур type_info будет уникальным для отдельных модулей, да, но, по крайней мере, в Windows, его небезопасно использовать для типов, содержащих более 1 модуля (приложения/динамические библиотеки).   -  person smerlin    schedule 19.04.2011


Ответы (4)



В type_info есть оператор ==() для сравнения описываемого им типа с типом другого объекта type_info. Объекты также гарантированно переживут программу.

Таким образом, если вы сохраните адреса двух type_info, вы можете использовать *p1 == *p2, чтобы увидеть, относятся ли они к одному и тому же типу.

person Bo Persson    schedule 19.04.2011

статический элемент данных, который инициализируется с помощью алгоритма, использующего счетчик? Затем используйте MyClass::id в качестве уникального идентификатора. А затем используйте виртуальные функции для получения уникального идентификатора на основе базового класса. Гарантируется переносимость, но требует небольшой поддержки, поскольку вам необходимо реализовать как статическую переменную, так и реализовать виртуальную функцию для каждого нового класса, который вы создаете. Но думаю, это не большая проблема, поскольку вы уже решили использовать C++, который, как известно, многословен. Это будет выглядеть так:

class Base { virtual int get_id() const=0; };
class Derived : public Base { static int id; int get_id() const { return id; } };
int algo() { static int count=0; count++; return count; }
static int Derived::id = algo();
person tp1    schedule 19.04.2011
comment
Это возможно, но разве RTTI не был придуман именно для того, чтобы мне не нужно было писать и поддерживать такой код? Это задача компилятора, а не моя. - person Kos; 19.04.2011
comment
ну, дело в том, что в С++ вы действительно иногда получаете лучший код, если вы действительно выполняете работу и пишете немного больший объем шаблонного кода. - person tp1; 19.04.2011

Похоже, что type_info::hash_code() предписывается для C++0x .

person paquetp    schedule 19.04.2011
comment
Осторожность! По стандарту: hash_code() не должен возвращать разные идентификаторы для двух разных типов. Это хэш-код, а не ключ. - person Christopher Oezbek; 24.11.2011
comment
Также это имеет свою стоимость. Я сделал несколько тестов, и hash_chode работает намного медленнее, чем type_index. - person 56ka; 14.01.2020