URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9300
[ Назад ]

Исходное сообщение
"typeid, RTTI, сравнить объект является ли классом"

Отправлено Fx , 23-Ноя-11 12:21 

// 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, но мне он не нужен, зачем эти накладные расходы? Напрямую можно ли сравнить?


Содержание

Сообщения в этом обсуждении
"typeid, RTTI, сравнить объект является ли классом"
Отправлено meantraitor , 23-Ноя-11 18:46 
>[оверквотинг удален]
>   Poly_Base* ppolybase = &polyderived;
>   cout << boolalpha << "same type? ";
>   cout << ( typeid(polyderived)==typeid(*ppolybase) ) << endl << endl;
> }
>

> Как правильно сравнить class Poly_Derived == typeid(*ppolybase) ?
> Т.е. Является ли указатель *ppolybase классом Poly_Derived?
> Во всех примерах в гугле(и примере выше) создают для этого объект polyderived,
> но мне он не нужен, зачем эти накладные расходы? Напрямую можно
> ли сравнить?

dynamic_cast?


"typeid, RTTI, сравнить объект является ли классом"
Отправлено Fx , 23-Ноя-11 19:27 

>> Как правильно сравнить 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 лишних объектов, но не элегантно как-то...

есть какие-то еще возможности?


"typeid, RTTI, сравнить объект является ли классом"
Отправлено elvenic , 23-Ноя-11 21:57 

> 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 которые проверяют тип обьекта...


"typeid, RTTI, сравнить объект является ли классом"
Отправлено Fx , 23-Ноя-11 23:01 

> А нельзя ли добавить виртуальный метод в базовый класс, и переопределить его
> в выведенных классах?
> и потом вместо цепочки 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';
    }



"typeid, RTTI, сравнить объект является ли классом"
Отправлено JohnProfic , 25-Ноя-11 22:31 

if (dynamic_cast<CDerived*>(b) != NULL) {
    // b is pointer to CDerived
}

по идее должно работать во всех компиляторах, ибо стандарт.

"typeid, RTTI, сравнить объект является ли классом"
Отправлено Fx , 14-Дек-11 04:39 
>
 
> if (dynamic_cast<CDerived*>(b) != NULL) {
>     // b is pointer to CDerived
> }
>

> по идее должно работать во всех компиляторах, ибо стандарт.

может кому-то может - это самый верный способ. спасибо JohnProfic

вариант с
if ( typeid(CDerived)==typeid(*b) )
работает для сравнения, но воспользоваться *b как объектом другого класса без dynamic_cast не даст.