![]() |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
![]() ![]() |
![]() |
Tony |
![]()
Сообщение
#1
|
Новичок ![]() Группа: Пользователи Сообщений: 17 Пол: Мужской Репутация: ![]() ![]() ![]() |
Доброго всем времени суток.
Имеется такой код: class CBase т.е. есть некий базовый абстрактный класс, у которого много наследников. Далее происходит вот что: CBase *pBase = new CDerv1; Вопрос : очевидно, например с помощью typeid мы можем узнать тип объекта, на который на самом деле указывает pBase. Существует ли простой способ автоматически преобразовать pBase из типа CBase* в тип того объекта, на который он на самом деле указывает (в данном случае в CDerv1*)? |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
Цитата Существует ли простой способ автоматически преобразовать pBase из типа CBase* в тип того объекта, на который он на самом деле указывает (в данном случае в CDerv1*)? Интересно, каким образом ты представляешь подобное преобразование? То есть, тебе надо на этапе компиляции завести переменную, которая была бы соответствующего типа, чтоб туда записать преобразованный Base->Derived указатель? Или в каком виде тебе это нужно, уточни... |
Tony |
![]()
Сообщение
#3
|
Новичок ![]() Группа: Пользователи Сообщений: 17 Пол: Мужской Репутация: ![]() ![]() ![]() |
Да, извиняюсь, что не уточнил. Есть некая перегруженная функция F, которая будет обрабатывать различные типы указателей(т.е. CDerv1*, CDerv2* и т.п).
P.S. Я понимаю, конечно, что можно написать как-то так: if ( typeid(*pBase).name() == "CDerv1" ) F( (CDerv1*)pBase ); но тогда получится, что при добавлении нового наследника придется дописывать новое условие. Возможно ли избежать этого? |
volvo |
![]()
Сообщение
#4
|
Гость ![]() |
Почему не написать полиморфную функцию:
void f(CBase *p) ? Зачем ты уходишь от механизма виртуальных функций, и хочешь делать это же вручную? Можно, кстати, Цитата if ( typeid(*pBase).name() == "CDerv1" ) F( (CDerv1*)pBase ); if(dynamic_cast<CDerv1*>(pBase)) f(dynamic_cast<CDerv1*>(pBase));, но хрен редьки не слаще... Хм... Ан нет, слаще. Под GCC твой вариант не работает (там строка в другом формате возвращается), а мой - работает. Или вот этот: if ( typeid(*pBase) == typeid(CDerv1)) f( (CDerv1*)pBase );, тоже работает. Но основной вопрос был озвучен выше, почему не виртуальные функции? |
Tony |
![]()
Сообщение
#5
|
Новичок ![]() Группа: Пользователи Сообщений: 17 Пол: Мужской Репутация: ![]() ![]() ![]() |
Да, ваш вопрос логичен. Но это видимо из-за того, что я слишком все упростил)
На самом деле функция f принимает два указателя (т.е. к примеру f(CDerv1*, CDerv2*)), т.е. она реализует попарное взаимодействие между объектами. Просто в данном случае получается так, что нельзя вытащить нужные данные объекта с помощью виртуальных функций(эти свойства слишком разные), а нужен просто сам объект; но опять-таки нельзя уйти и от виртуальных функций, так как без них все бы сильно усложнилось. Мне почему-то казалось, что возможность такого приведения типов должна быть реализована в языке, и я просто о ней не знаю.. Сообщение отредактировано: Tony - 10.08.2010 16:23 |
volvo |
![]()
Сообщение
#6
|
Гость ![]() |
А... Ты, значит, мультиметоды реализуешь?
![]() Или С. Майерс, "Наиболее эффективное использование С++" - правило №31: "Создавайте функции, виртуальные по отношению более чем к одному объекту" |
Tony |
![]()
Сообщение
#7
|
Новичок ![]() Группа: Пользователи Сообщений: 17 Пол: Мужской Репутация: ![]() ![]() ![]() |
Да, volvo, огромное спасибо. Это как раз то, что мне было нужно) Жаль только, что в C++ их пока нет.
|
![]() ![]() |
![]() |
Текстовая версия | 19.07.2025 14:52 |