// type_info example
#include <iostream>
#include <typeinfo>
using namespace std;struct Poly_Base {virtual void Member(){}};
struct Poly_Derived: Poly_Base {};int main() {
// polymorphic types:
Poly_Derived polyderived;
Poly_Base* ppolybase = &polyderived;cout << boolalpha << "same type? ";
cout << ( typeid(polyderived)==typeid(*ppolybase) ) << endl << endl;
}Как правильно сравнить class Poly_Derived == typeid(*ppolybase) ?
Т.е. Является ли указатель *ppolybase классом Poly_Derived?
Во всех примерах в гугле(и примере выше) создают для этого объект polyderived, но мне он не нужен, зачем эти накладные расходы? Напрямую можно ли сравнить?
>[оверквотинг удален]
> Poly_Base* ppolybase = &polyderived;
> cout << boolalpha << "same type? ";
> cout << ( typeid(polyderived)==typeid(*ppolybase) ) << endl << endl;
> }
>
dynamic_cast?
>> Как правильно сравнить class Poly_Derived == typeid(*ppolybase) ?
>> Т.е. Является ли указатель *ppolybase классом Poly_Derived?
>> Во всех примерах в гугле(и примере выше) создают для этого объект polyderived,
>> но мне он не нужен, зачем эти накладные расходы? Напрямую можно
>> ли сравнить?
> dynamic_cast?спасибо. подходит, но не совсем. Может еще варианты?
не организовать удобное ветвление программы, если у базового класса например 5 классов-наследников:
if ( *ppolybase == Class Poly_Derived)
{
// делаем 1
}
else if ( *ppolybase == Class Poly_DerivedTwo)
{
// делаем 2
}на вскидку, с dynamic_cast прийдется создать 5 лишних указателей, и сделать до 5 попыток dynamic_cast, чтобы понять какой это класс. 5 лишних указателей, конечно, лучше чем создание 5 лишних объектов, но не элегантно как-то...
есть какие-то еще возможности?
> if ( *ppolybase == Class Poly_Derived)
> {
> // делаем 1
> }
> else if ( *ppolybase == Class Poly_DerivedTwo)
> {
> // делаем 2
> }А нельзя ли добавить виртуальный метод в базовый класс, и переопределить его в выведенных классах?
class Poly_Base
{
virtual doSomething();
}class Poly_Derived
{
virtual doSomething()
{
// делаем 1
}
}class Poly_DeruivedTwo
{
virtual doSomething()
{
// делаем 2
}
}и потом вместо цепочки if-else if-else if просто визвать этот виртуальный метод:
ppolybase = [создать или получить откуда-то извне указатель на выведенный из Poly_Base обьект];
ppolybase->doSomething();В принципе виртуальные методы для этого и придуманы были - чтобы избавиться от длинных цепочек if-else которые проверяют тип обьекта...
> А нельзя ли добавить виртуальный метод в базовый класс, и переопределить его
> в выведенных классах?
> и потом вместо цепочки if-else if-else if просто визвать этот виртуальный метод:
> ppolybase = [создать или получить откуда-то извне указатель на выведенный из Poly_Base
> обьект];
> ppolybase->doSomething();
> В принципе виртуальные методы для этого и придуманы были - чтобы избавиться
> от длинных цепочек if-else которые проверяют тип обьекта...было бы красиво, но в данном случае связь у виртуальных классов очень надуманая. один - просто контейнер для string, а второй контейнер для параметров основываясь на которых другая совсем часть кода делает свою работу. т.е. зауши притянуто будет, и эти виртуальные классы хранители информации разжирнеют.
вообще я нашел, похоже, решение... методом научного тыка... и она оказалось очень простым.
незнаю насколько это верно и валидно, ниодного такого примера в гугле не нашел, когда имя класса напрямую в typeid сували( не объект), но под виндой компилятор это отрабатывает как нужно. в рабочей среде еще не проверял...
class CBase { virtual void f(){} };
class CDerived : public CBase {};
class CDerivedOne : public CBase {};int main () {
try {
CBase* a = new CBase;
CBase* b = new CDerived;
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
cout << "*a is: " << typeid(*a).name() << '\n';
cout << "*b is: " << typeid(*b).name() << '\n';
if ( typeid(CDerived)==typeid(*b) )
{
cout << " goal *b is Cbase ! " << '\n';
}
if (dynamic_cast<CDerived*>(b) != NULL) {
// b is pointer to CDerived
}
по идее должно работать во всех компиляторах, ибо стандарт.
>
> if (dynamic_cast<CDerived*>(b) != NULL) {
> // b is pointer to CDerived
> }
>
> по идее должно работать во всех компиляторах, ибо стандарт.может кому-то может - это самый верный способ. спасибо JohnProfic
вариант с
if ( typeid(CDerived)==typeid(*b) )
работает для сравнения, но воспользоваться *b как объектом другого класса без dynamic_cast не даст.