The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"typeid, RTTI, сравнить объект является ли классом"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"typeid, RTTI, сравнить объект является ли классом"  +/
Сообщение от Fx (ok) on 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, но мне он не нужен, зачем эти накладные расходы? Напрямую можно ли сравнить?

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "typeid, RTTI, сравнить объект является ли классом"  +/
Сообщение от meantraitor on 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?

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "typeid, RTTI, сравнить объект является ли классом"  +/
Сообщение от Fx (ok) on 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 лишних объектов, но не элегантно как-то...

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

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

3. "typeid, RTTI, сравнить объект является ли классом"  +/
Сообщение от elvenic (ok) on 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 которые проверяют тип обьекта...

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "typeid, RTTI, сравнить объект является ли классом"  +/
Сообщение от Fx (ok) on 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';
    }


Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

5. "typeid, RTTI, сравнить объект является ли классом"  +/
Сообщение от JohnProfic (ok) on 25-Ноя-11, 22:31 

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

по идее должно работать во всех компиляторах, ибо стандарт.
Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

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

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

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

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

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру