Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как получить тип через указатель на базовый класс? 
V
    Опции темы
georain
Дата 20.12.2007, 01:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Подскажите, что то я запутался.

Есть дерево полиморфных классов, есть указатель на базовый класс.
Как я могу (и могу ли вообще) получить указатель на класс, на который указывает указатель на базовый класс.

 smile 
PM MAIL   Вверх
Daevaorn
Дата 20.12.2007, 01:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



"Указателей на класс" в С++ не существует.
PM MAIL WWW   Вверх
georain
Дата 20.12.2007, 02:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Извините, неправильно (сокращённо) выразился.

Указатель с типом производного класса?

Код

Base * b_ptr;
DerivedA * d_ptrA;
DerivedB * d_ptrB;
DerivedC * d_ptrC;


Нужно получить d_ptrA, d_ptrB или d_ptrС каким-либо образом из b_ptr.

PM MAIL   Вверх
dizzy1984
Дата 20.12.2007, 07:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 675
Регистрация: 15.2.2007

Репутация: 3
Всего: 25



Если b_ptr указывает на DerivedA, то можно так
Код

d_ptrA = dynamic_cast <DerivedA *>(b_ptr)

или с помощью c-cast
Код

d_ptrA = (DerivedA *)b_ptr;

PM MAIL   Вверх
georain
Дата 20.12.2007, 07:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Так это понятно  smile

А если мы заранее не знаем что он указывает на DerivedA?
Мы может определить это через специальную виртуальную функцию.
Но как это автоматизировать?

Хочется что-то типа
b_ptr = dynamic_cast <(b_ptr->get_my_type)>(b_ptr)  smile 
только без RTTI, ну и чтоб работало)

Я думаю что похоже придётся для каждого класса специализированный шаблон заводить...
PM MAIL   Вверх
dizzy1984
Дата 20.12.2007, 09:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 675
Регистрация: 15.2.2007

Репутация: 3
Всего: 25



А можно привести ситуацию в которой такое преобразование необходимо?
PM MAIL   Вверх
MAKCim
Дата 20.12.2007, 10:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(georain @  20.12.2007,  07:45 Найти цитируемый пост)
Хочется что-то типа
b_ptr = dynamic_cast <(b_ptr->get_my_type)>(b_ptr)  smile 
только без RTTI, ну и чтоб работало)

нельзя
в С++ статическая типизация


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Alek86
Дата 20.12.2007, 11:01 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



georain, а можно поинтересоваться, зачем это тебе нужно?
по-моему, ты пренебрегаешь такой хорошей штукой, как полиморфизм

скорее всего, твоя проблема решается с помощью виртуальных функций.


--------------------
user posted image    user posted image
PM MAIL   Вверх
MAKCim
Дата 20.12.2007, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



 smile 
Alek86, 
dizzy1984, 
я вот не понимаю, зачем задавать подобные вопросы
это самый что ни на есть прямой уход от поставленной задачи
что не есть хорошо
человек определенно спросил, можно ли, дескать, сделать так-то и так-то
а вы начинаете демогогию типа "а зачем тебе это нужно"
не знаете - не отвечайте
извините за резкость...накипело




--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
baldina
Дата 20.12.2007, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата

только без RTTI, ну и чтоб работало)


без RTTI вообще никак (ну только если ты сам не хранишь поле типа). RTTI нужен для dynamic_cast.

Цитата

скорее всего, твоя проблема решается с помощью виртуальных функций. 


полностью согласен.

Цитата

Хочется что-то типа
b_ptr = dynamic_cast <(b_ptr->get_my_type)>(b_ptr) 


сам то понял что сказал? у тебя уже есть b_ptr. А если ты хочешь и можешь использовать его полиморфно, приведение типа не нужно.


Цитата

Base * b_ptr;
DerivedA * d_ptrA;
DerivedB * d_ptrB;
DerivedC * d_ptrC;

Нужно получить d_ptrA, d_ptrB или d_ptrС каким-либо образом из b_ptr.

Это в smalltalk такой подход. Мы не знаем, чем на самом деле является класс и запрашиваем возможность использования его в качестве одного из подтипов. Если получается - используем. Для этого как раз может подойти dynamic_cast.

Например, у тебя в массиве хранятся указатели на объекты типа Base, но реально имеющие производный тип. И ты хочешь над всеми, кто указывает на DerivedA, выполнить специфичную для DerivedA (не полиморфную) операцию. Будет так:
Код

std::vector<Base*> b_ptrs;
for (int i=0; i < b_ptrs.size(); ++i)
{
  DerivedA* d_ptrA = dynamic_cast<DerivedA*>(b_ptrs[i]);
  if (d_ptrA != 0)
  {
     // ok, b_ptrs[i] указывает на DerivedA
     d_ptrA->some_func();
  }
}


PM MAIL   Вверх
MAKCim
Дата 20.12.2007, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(baldina @  20.12.2007,  12:00 Найти цитируемый пост)
сам то понял что сказал? у тебя уже есть b_ptr. А если ты хочешь и можешь использовать его полиморфно, приведение типа не нужно.

я отлично понял, что имел в виду georain
и объяснил, что в С++ такое невозможно 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Alek86
Дата 20.12.2007, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



оффтоп

Цитата(MAKCim @  20.12.2007,  11:58 Найти цитируемый пост)
  Alek86, dizzy1984, я вот не понимаю, зачем задавать подобные вопросы


я "отвечал" не на первый вопрос темы (на него уже ответили) а на этот:

Цитата(georain @  20.12.2007,  07:45 Найти цитируемый пост)
Хочется что-то типаb_ptr = dynamic_cast <(b_ptr->get_my_type)>(b_ptr)   только без RTTI, ну и чтоб работало)



пытался, так сказать, как Христос, не накормить рыбой а научить ловить smile

Это сообщение отредактировал(а) Alek86 - 20.12.2007, 12:24


--------------------
user posted image    user posted image
PM MAIL   Вверх
baldina
Дата 20.12.2007, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата

я отлично понял, что имел в виду georain

MAKCim, это автору предназначалось.
PM MAIL   Вверх
MAKCim
Дата 20.12.2007, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(baldina @  20.12.2007,  12:31 Найти цитируемый пост)
MAKCim, это автору предназначалось. 

 smile 
я думаю, если другие поняли, то и автор должен понимать


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
georain
Дата 20.12.2007, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Ладно, объясняю зачем мне это нужно. Всё опять же нужно для оптимизации по скорости. Возможно есть какой-то другой способ решения, если знаете подскажите пожалуйста.

Есть довольно большое дерево полиморфных классов, в каждом классе есть тоже довольно много виртуальных функций.
Специфика программы в том, что часто в одном месте (всмысле последовательно) из одного из классов вызывается много функций подряд в разных последовательностях.
Так вот хочется уменьшить накладные расходы на вызовы виртуальных функций, и сократить их до одной, а потом вызывать остальные статически, ведь по идее с помощь виртуальной функции можно получить информацию о типе, а имея информацию о типе можно вызывать функции непосредственно (статически).

Т.е. что-то типа
Код

class Derived: public Base
{
inline virtual void func();
}

ptr * Base = derived;

/*каким-то магическим способом получаем D_ptr с типом Derived*/

(*D_ptr)->func() //здесь происходить прямой вызов или даже подстановка 



MAKCim, спасибо за понимание. Я пока писал понял что действительно в с++ так нельзя... если без шаблонов...))

baldina, с dynamic_cast пришлось бы делать перебор для всех классов, а он сам по себе очень не дешёвый - в итоге смысла нет.

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

Это сообщение отредактировал(а) georain - 20.12.2007, 13:56
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0994 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.