Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Почему не происходит чуда ?


Автор: SABROG 12.3.2008, 22:56
Есть куча разных классов. Есть указатели на каждый. Указатели должны пихаться в item'ы скажем listbox'a. Хочу воспользоваться чудом RTTI и идентифицировать класс

Код

    if (typeid(*(void *)метод_для_взятия_указателя_через_индекс(i)) == typeid(ClassA))
    {
        ...
    }
    else if (typeid(*(void *)метод_для_взятия_указателя_через_индекс(i)) == typeid(ClassB))
    {
        ...
    }


На этапе компиляции такая ошибка: error: `void*' is not a pointer-to-object type

Т.е. чуда не будет ?

Автор: bsa 12.3.2008, 23:10
не приводи к void*. А приводи к указателю на базовый класс.

Автор: SABROG 12.3.2008, 23:14
Цитата(bsa @ 12.3.2008,  23:10)
не приводи к void*. А приводи к указателю на базовый класс.

А тогда какой смысл, если я буду знать базовый класс, то мне и typeid нафиг не нужен. Я думал компилятор каким-то макаром соотносит циферки из указателя к типу "где-то у себя". Хочу чуда, я ему пихаю любую ссылку или указатель, а он мне говорит че я ему посунул.

Автор: bsa 12.3.2008, 23:29
SABROG, сделай класс: 
Код
struct MyBaseForAll
{
    virtual ~MyBaseForAll(){}
};
И унаследуй все классы от него.

Автор: SABROG 12.3.2008, 23:48
Цитата(bsa @ 12.3.2008,  23:29)
SABROG, сделай класс: 
Код
struct MyBaseForAll
{
    virtual ~MyBaseForAll(){}
};
И унаследуй все классы от него.

Я еще понимаю, когда можно получить базовый класс из наследника, но ведь обратного не существует:

Код

    struct MyBaseForAll
    {
        virtual ~MyBaseForAll(){}
    };
    struct A :public MyBaseForAll
    {
        int var1;
    };
    struct B :public MyBaseForAll
    {
        int var2;
    };
    B *pvar1 = new B;
    pvar1->var2 = 2;
    MyBaseForAll *var = pvar1;
    if (typeid(*var) == typeid(B))
    {
        B *v = var;
        log(QString("B: %1").arg(v->var2));
    }
    else if (typeid(*var) == typeid(A))
    {
        A *v = var;
        log(QString("A: %1").arg(v->var1));
    }


error: invalid conversion from `MyBaseForAll*' to `B*'

Автор: bsa 13.3.2008, 00:01
dynamic_cast рулит.  smile 

Автор: korian 13.3.2008, 00:05
а так буит работать?
Код

 if (typeid((void *)метод_для_взятия_указателя_через_индекс(i)) == typeid(ClassA*))

в какой-то умной книге читал, что-то типа такого:
если вы решили, что вам нужно знать/получать тип объекта (это касается и того, если вы в самом объекте храните его тип), задумайтесь! и используйте виртуальные функции.

а чуда нету, потому что тип void использовать нельзя
*(void*) = void
я правда хз, будет ли typeid работать с указателями вообще, и с указателем void* вчастности

Автор: SABROG 13.3.2008, 00:14
С dynamic_cast действительно проканало, теперь я нереально буду рулить с указателями на базе MyBaseForAll.  smile Чудо все-таки произошло!  smile 

Цитата(korian @  13.3.2008,  00:05 Найти цитируемый пост)
а чуда нету, потому что тип void использовать нельзя
*(void*) = void
я правда хз, будет ли typeid работать с указателями вообще, и с указателем void* вчастности


"Нафиг нужна музыкальная школа, когда есть пример Паганини Никколо" © Ленинград

Я теперь в MyBaseForAll могу запихнуть хоть void * членом класса.

Автор: Hehe 18.3.2008, 04:49
Используй CLR и будет тебе счастье =) Ну во всяком случае - гемора меньше. =)

Автор: Lazin 18.3.2008, 09:39
так к слову...
Цитата(MSDN)

The typeid operator does a run-time check when applied to an l-value of a polymorphic class type

то-есть чтобы чудо произошло, нужно, что-бы у класса была хотя-бы одна виртуальная функция  smile 

Автор: SABROG 18.3.2008, 09:46
Я отказался от rtti, если компилятор создает сам таблицы и шарит по ним, то какой в этом смысл, если я могу делать тоже самое и со своей оптимизацией и уже никто не сможет отключить rtti у компилятора и сделать тем самым нерабочую программу.

Автор: Lazin 18.3.2008, 09:59
если у тебя в коде используется dynamic_cast, то ты уже полюбому от RTTI зависишь

Автор: SABROG 18.3.2008, 11:38
Цитата(Lazin @ 18.3.2008,  09:59)
если у тебя в коде используется dynamic_cast, то ты уже полюбому от RTTI зависишь

Нет, не используется. Я просто вернулся к тому с чего начал, пихаю в итемы листбокса пару QPair<int, rootClass>, где int это Enum определяющий тип параметра, а rootClass корень дерева. В итоге, по смыслу, получается нечто вроде этого:

Код

enum {par1, par2, par3};
QPair<int, rootClass *> data = метод_получения_пары_из_итема(index);
int type = data.first();
rootClass *root = data.second();
switch(type)
{
case par1:
root->par1;
break;
case par2:
root->par2;
}


Только мне кажется Qt зависит, т.к. я вижу ключ -rtti при компиляции.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)