Предположим, что у меня есть абстрактный базовый класс Parent и подклассы Child1 и Child2. Если у меня есть функция, которая принимает Parent *, есть ли способ (возможно, с RTTI?), Чтобы определить во время выполнения, является ли Child1 * или Child2 *, что функция фактически получила?
До сих пор мой опыт работы с RTTI был таким: когда foo является Parent *, typeid (foo) возвращает typeid (Parent *) независимо от дочернего класса, членом которого является foo.
Вам нужно взглянуть на typeid разыменованного указателя, а не на сам указатель; Т.е. typeid (* foo), а не typeid (foo). Запрос о разыменованном указателе даст вам динамический тип; если вы спросите о самом указателе, вы получите статический тип, как вы заметили.
Ты можешь использовать std::dynamic_cast
за это.
Parent* ptr = new Child1();
if(dynamic_cast<Child1*>(ptr) != nullptr) {
// ptr is object of Child1 class
} else if(dynamic_cast<Child2*>(ptr) != nullptr) {
// ptr is object of Child2 class
}
Также, если вы используете умные указатели, такие как std::shared_ptr
, вы можете проверить это так:
std::shared_ptr<Parent> ptr(new Child1());
if(std::dynamic_pointer_cast<Child1>(ptr) != nullptr) {
// ptr is object of Child1 class
} else if(std::dynamic_pointer_cast<Child2>(ptr) != nullptr) {
// ptr is object of Child2 class
}
Конечно:
BaseClass *bptr = // whatever, pointer to base class
SubclassOne *safe_ptr_one = dynamic_cast<SubclassOne *>(bptr);
if (safe_ptr_one != nullptr) {
// Instance of SubclassOne
} else {
// not an instance of SubclassOne, try the other one
SubclassTwo *safe_ptr_two = dynamic_cast<SubclassTwo *>(bptr);
if (safe_ptr_two != nullptr) {
// Instance of SubclassTwo
} else {
// it wasn't either one :'(
}
}