Числовой уникальный идентификатор класса через typeid - PullRequest
12 голосов
/ 19 апреля 2011

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

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

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

Ответы [ 4 ]

6 голосов
/ 06 октября 2014

std :: type_index (C ++ 11) может использоваться в контейнерах для хранения значений на основе типа. Это не даст вам номер.

std::type_index index = std::type_index (typeid (int));

Подробнее: http://en.cppreference.com/w/cpp/types/type_index

Класс type_index является классом-оболочкой для объекта std::type_info, который может использоваться как индекс в ассоциативных и неупорядоченных ассоциативных контейнерах . Связь с type_info объектом поддерживается через указатель, поэтому type_index имеет значение CopyConstructible и CopyAssignable.

4 голосов
/ 19 апреля 2011

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

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

0 голосов
/ 19 апреля 2011

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

0 голосов
/ 19 апреля 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();
...