Есть два способа сделать это. Во-первых, вы можете использовать оператор typeid
, который возвращает структуру type_info
, содержащую информацию о типе объекта. Например:
Base* ptr = /* ... */
if (typeid(*ptr) == typeid(DerivedType)) {
/* ... ptr points to a DerivedType ... */
}
Обратите внимание, что вы должны использовать typeid(*ptr)
, а не typeid(ptr)
здесь. Если вы используете typeid(ptr)
, вы получите объект type_info
для Base*
, поскольку указатель имеет тип Base*
независимо от того, на что он указывает.
Важным моментом, который следует отметить, является то, что он проверит, на что ptr
указывает точно как DerivedType
. Если ptr
указывает на объект типа, производного от DerivedType
(возможно, EvenMoreDerivedType
), этот код не будет работать правильно.
Альтернативный способ проверки того, что вы указываете на объект некоторого типа, который немного более устойчив, - это использование оператора dynamic_cast
. dynamic_cast
выполняет проверенный тип преобразования во время выполнения, который выдаст действительный указатель, если приведение выполнено успешно, и NULL в противном случае. Например:
Base* ptr = /* ... */;
DerivedType* derived = dynamic_cast<DerivedType*>(ptr);
if (derived) {
/* ... points to a DerivedType ... */
}
Это дает дополнительное преимущество: если ptr
указывает на что-то вроде EvenMoreDerivedType
, приведение все равно будет успешным, поскольку EvenMoreDerivedType
наследуется от DerivedType
.
В заключение я иногда вижу код, подобный следующему:
Base* ptr = /* ... */
if (DerivedType* derived = dynamic_cast<DerivedType*>(ptr)) {
/* ... points to a DerivedType ... */
}
Это локально ограничивает указатель derived
на тело оператора if
и использует тот факт, что ненулевые значения оцениваются в true
в C ++. Лично я считаю, что это легче читать и меньше подвержено ошибкам, но во что бы то ни стало идти с тем, что легче для вас.
Надеюсь, это поможет!