Идентифицировать подкласс по указателю на его базовый класс?

Предположим, что у меня есть абстрактный базовый класс Parent и подклассы Child1 и Child2. Если у меня есть функция, которая принимает Parent *, есть ли способ (возможно, с RTTI?), Чтобы определить во время выполнения, является ли Child1 * или Child2 *, что функция фактически получила?

До сих пор мой опыт работы с RTTI был таким: когда foo является Parent *, typeid (foo) возвращает typeid (Parent *) независимо от дочернего класса, членом которого является foo.

8

Решение

Вам нужно взглянуть на typeid разыменованного указателя, а не на сам указатель; Т.е. typeid (* foo), а не typeid (foo). Запрос о разыменованном указателе даст вам динамический тип; если вы спросите о самом указателе, вы получите статический тип, как вы заметили.

6

Другие решения

Ты можешь использовать 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
}
5

Конечно:

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 :'(
}
}
3
По вопросам рекламы [email protected]