Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
3 / 3 / 1
Регистрация: 10.11.2012
Сообщений: 63
1

dynamic_cast

25.10.2013, 15:08. Показов 3034. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Помогите разобраться с dynamic_cast, а точнее с вот этой записью
C++ (Qt)
1
2
3
4
5
6
7
8
9
void f() {
   A* pa = new A;
   B* pb = new B;
   void* pv = dynamic_cast<void*>(pa);
   // pv now points to an object of type A
 
   pv = dynamic_cast<void*>(pb);
   // pv now points to an object of type B
}
Тоесть, если я сделаю вот так
C++ (Qt)
1
2
3
Derived* pd = new Derived;
Base* pb = dynamic_cast<Base*>(pa);
void* pbd = dynamic_cast<void*>(pb);
то pbd будет указывать на Derived? И если так, то как можно после этого использовать методы этого класса?

Или здесь смысл именно в том, чтобы передать в void* адрес класса? Тогда почему не использовать бы какой-нибудь другой каст?

P.S: dynamic_cast можно применять только от Derived к Base?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.10.2013, 15:08
Ответы с готовыми решениями:

Dynamic_cast
#include &lt;iostream&gt; #define STOP cin.get(); using std::cin; using std::cout; class A {...

dynamic_cast
Подскажите пожалуйста, возникла проблема. Есть базовый клас CStep. И пока один наследник: class...

dynamic_cast
Уважаемые, подскажите теорию. Как устроен данный каст? Не нашел его определений. В студии он зашит...

dynamic_cast
#include &lt;iostream&gt; class B { public: virtual void foo(){std::cout&lt;&lt;&quot;B&quot;;} private: ...

16
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
25.10.2013, 15:11 2
Цитата Сообщение от Eugine Посмотреть сообщение
Тогда почему не использовать бы какой-нибудь другой каст?
это у тебя надо спросить. почему не использовать бы какой-нибудь другой каст?

Добавлено через 1 минуту
Цитата Сообщение от Eugine Посмотреть сообщение
C++
1
Base* pb = dynamic_cast<Base*>(pa);
Цитата Сообщение от Eugine Посмотреть сообщение
то pbd будет указывать на Derived?
а кто такой pa ?
0
3 / 3 / 1
Регистрация: 10.11.2012
Сообщений: 63
25.10.2013, 15:14  [ТС] 3
Я просто разбираюсь с dynamic_cast, он позволяет работать с классами и void*. И вот возник вопрос, чем void* так выделился.

Добавлено через 1 минуту
Цитата Сообщение от Jupiter Посмотреть сообщение
это у тебя надо спросить. почему не использовать бы какой-нибудь другой каст?

Добавлено через 1 минуту


а кто такой pa ?
извиняюсь, там не pa, а pd

C++ (Qt)
1
2
3
Derived* pd = new Derived;
Base* pb = dynamic_cast<Base*>(pd);
void* pbd = dynamic_cast<void*>(pb);
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
25.10.2013, 15:15 4
Цитата Сообщение от Eugine Посмотреть сообщение
Я просто разбираюсь с dynamic_cast, он позволяет работать с классами и void*
чорд, а я и не знал блин (интересно, где такое пишут? в топку этот источник), а ты знаешь что ножем можно резать хлеб, а можно и пальцы отрезать?

почитай хотя бы в вики про dynamic_cast
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
25.10.2013, 15:25 5
Тут неплохо описаны разные приведения типов на основе ***_cast

Не по теме:

Кстати, я недавно ввёл в язык С++ еще один метод приведения типа: cast_away<type>(variable) - это один из самых нахальных и безжалостных методов приведения типов. Будет введен в стандарт языка С++18

1
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
25.10.2013, 16:47 6
Цитата Сообщение от Eugine Посмотреть сообщение
то pbd будет указывать на Derived? И если так, то как можно после этого использовать методы этого класса?
Цитата Сообщение от Jupiter Посмотреть сообщение
чорд, а я и не знал блин (интересно, где такое пишут? в топку этот источник), а ты знаешь что ножем можно резать хлеб, а можно и пальцы отрезать?
К void* иногда нужно приводить. При множественном наследовании это позволяет получить указатель на самое начало объекта.
0
oxotnik
25.10.2013, 16:51
  #7

Не по теме:

не знал, что можно кастить к воиду*

0
205 / 165 / 41
Регистрация: 25.10.2013
Сообщений: 527
25.10.2013, 16:52 8
Почему при приведении к <void *> не использовать static_cast?
Это намного быстрее.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
25.10.2013, 16:54 9
Цитата Сообщение от Shtirliz72 Посмотреть сообщение
Почему при приведении к <void *> не использовать reinterpret_cast?
Это намного быстрее.
Быстрее чем что?
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
25.10.2013, 16:55 10
Цитата Сообщение от Shtirliz72 Посмотреть сообщение
Почему при приведении к <void *> не использовать reinterpret_cast?
Это намного быстрее.
Потому что при множественном наследовании полученный указатель не будет указывать на начало объекта.
0
205 / 165 / 41
Регистрация: 25.10.2013
Сообщений: 527
25.10.2013, 16:59 11
Цитата Сообщение от castaway Посмотреть сообщение
Быстрее чем что?
Не, это я неверно написал, уже исправил. reinterpret_cast нельзя использовать с void* .

Цитата Сообщение от ct0r Посмотреть сообщение
Потому что при множественном наследовании полученный указатель не будет указывать на начало объекта.
Ясно. static_cast это тоже касается?
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
25.10.2013, 17:05 12
Цитата Сообщение от Shtirliz72 Посмотреть сообщение
Ясно. static_cast это тоже касается?
Да. Ни один каст кроме dynamic_cast не использует RTTI.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
 
struct A { int a; virtual ~A(){} };
struct B { int b; virtual ~B(){} };
struct C: A, B { int c; };
 
void foo(B* obj)
{
    cout << static_cast<void*>(obj) << endl;
    cout << dynamic_cast<void*>(obj);
}
 
int main() {
    C* c = new C;
    cout << c << endl;
    foo(c);
    return 0;
}
0x9166008
0x9166010
0x9166008
2
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
25.10.2013, 17:08 13
А в чем смысл преобразования к типу void * в данном случае?

Добавлено через 3 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
 
using namespace std;
 
struct A { int a; virtual ~A(){} };
struct B { int b; virtual ~B(){} };
struct C: A, B { int c; };
 
int main()
{
    C* c = new C;
    cout << c << endl;
    cout << (void *)c << endl;
    cout << static_cast<void*>(c) << endl;
    cout << dynamic_cast<void*>(c) << endl;
    cout << reinterpret_cast<void*>(c) << endl;
 
    return 0;
}
0x9e2e58
0x9e2e58
0x9e2e58
0x9e2e58
0x9e2e58
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
25.10.2013, 17:14 14
Цитата Сообщение от castaway Посмотреть сообщение
А в чем смысл преобразования к типу void * в данном случае?
Ты имеешь в виду зачем нам нужно получать указатель на начало объекта или что?

Ну в твоем коде очевидно, что адреса будут одинаковые. Потому что нет преобразований, которые бы сдвигали указатель (у меня это из C* в B*).
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
25.10.2013, 17:23 15
ct0r, в 12-м посте у меня такой же вывод как и у тебя.. видимо я чего-то недопонимаю.. Чего именно? Почему в функции объект имеет другое "основание" ?

Почему следующий вариант выдает одинаковые значения:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
 
using namespace std;
 
struct A { int a; virtual ~A(){} };
struct B { int b; virtual ~B(){} };
struct C: A, B { int c; };
 
void test( C * c ) {
    cout << c << endl;
    cout << (void *)c << endl;
    cout << static_cast<void*>(c) << endl;
    cout << dynamic_cast<void*>(c) << endl;
    cout << reinterpret_cast<void*>(c) << endl;
}
 
int main()
{
    C* c = new C;
    test( c );
 
    cout << c << endl;
    cout << (void *)c << endl;
    cout << static_cast<void*>(c) << endl;
    cout << dynamic_cast<void*>(c) << endl;
    cout << reinterpret_cast<void*>(c) << endl;
 
    return 0;
}
?

0x502e58
0x502e58
0x502e58
0x502e58
0x502e58
0x502e58
0x502e58
0x502e58
0x502e58
0x502e58
Добавлено через 4 минуты
Тьфу, блин.. у тебя ж там другой объект..
0
Игогошка!
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
25.10.2013, 17:25 16
C* c = new C; - тут c указывает на объект самого производного класса
При вызове функции идет преобразование из C* в B*, после которого с указывает уже на подобъект класса В, который неявно содержится в классе С.
Только dynamic_cast пользуется информацией о полиморфных типах, поэтому только он потом может восстановить указатель на самый производный класс.
Это полезная фича, когда нам нужно уметь отличать подобъекты одного объекта от других подобъектов. Или при сериализации.
1
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
25.10.2013, 17:27 17
Я понял что ты хотел сказать. dynamic_cast приводит тип к указателю производного.
0
25.10.2013, 17:27
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.10.2013, 17:27
Помогаю со студенческими работами здесь

Dynamic_cast реализация
Добрый вечер, есть застоявшаясь фраза: &quot;dynamic_cast&lt;Type*&gt;( pointer ) очень медленное, его...

Dynamic_cast и полиморфизм
Задача: В листинге 15.16 после каждого блока try находятся два блока catch, поэтому исключение...

Работа с dynamic_cast
Всем привет! Есть Абстрактный класс Transport. Есть три наследника: Plain, Train, Ship. Есть массив...

Объясните dynamic_cast
дали задание разобраться с dynamic_cast, что это такое и с чем его едят. Прочитал информацию про...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru