Есть два способа сделать это. Во-первых, вы можете использовать оператор 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 ++. Я лично считаю это более легким для чтения и менее подверженным ошибкам, но, во что бы то ни стало, с вашим самым легким.
Надеюсь, это поможет!