Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
 Аватар для stzer
140 / 110 / 60
Регистрация: 26.10.2013
Сообщений: 314

Не могу разобраться с dynamic_cast

26.07.2014, 13:41. Показов 1160. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
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
class Base
{
public:
    virtual void info()
    {
        cout<<"Base"<<endl;
    }
};
 
class Derived : public Base
{
public:
    void info()
    {
        cout<<"Derived"<<endl;
    }
};
 
void main()
{
    Base *bp, base;
    Derived *dp, derived;
    bp=&base;
    bp->info();//Выведет Base
    dynamic_cast<Derived*>(bp);
    bp->info(); //Выведет Base, а мне нужно Derived
    system("pause");
}
Никак не могу разобраться с этим оператором.
Книги и статьи в интернете не помогли, помогите пожалуйста.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.07.2014, 13:41
Ответы с готовыми решениями:

Не могу разобраться с С++
Всем Привет, так я кодеру в Делфи. Не давно нашел что мне нужно но оy написан на С. Вот и начался у меня проблемы с кодами. Вот часть...

не могу разобраться..
Вывести на экран все натуральные числа из диапазона от A до B, в записи которых цифра 7 встречается ровно N раз. При отсутствии чисел с...

массивы.не могу разобраться
1. В массиве X из N элементов (N не больше 30) определить максимальный элемент и его номер. Число N и значения элементов массива задаются...

14
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
26.07.2014, 13:59
Цитата Сообщение от stzer Посмотреть сообщение
dynamic_cast<Derived*>(bp);
Во-первых, результат dynamic_cast нужно чему-то присвоить. Он не изменяет свой аргумент.
Во-вторых, он не поможет тебе сделать то, чего ты хочешь

Добавлено через 6 минут
Вот.
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
class Base
{
public:
    virtual void info()
    {
        cout<<"Base"<<endl;
    }
};
 
class Derived : public Base
{
public:
    void info()
    {
        cout<<"Derived"<<endl;
    }
};
 
int main()
{
    Base *bp, base;
    Derived *dp, derived;
    bp=&base;
    bp->info();//Выведет Base
    bp=&derived;
    bp->info(); //Выведет Derived
    system("pause");
}
Ну или объясни подробнее чего хочешь добиться.
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
26.07.2014, 13:59
Цитата Сообщение от DrOffset Посмотреть сообщение
Во-первых, результат dynamic_cast нужно чему-то присвоить.
Не обязательно, особенно если тип ссылочный.
stzer, чтобы получить вывод характерный для производного класса указатель должен указывать на объект этого (производного) класса.
Т.е. в первом приближении достаточно добавить:
C++
1
bp=&derived;
0
 Аватар для stzer
140 / 110 / 60
Регистрация: 26.10.2013
Сообщений: 314
26.07.2014, 14:00  [ТС]
DrOffset, Ладно, хорошо.
dynamic_cast используется для проверки типов объектов
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
30
31
32
33
34
35
#include <typeinfo>
 
class Base
{
    virtual void vertFunc()
    { }
};
class Derv1 : public Base
{ };
class Derv2 : public Base
{ };
bool isDerv1(Base *pUnknown)
{
    Derv1 *pDerv1;
    if(pDerv1=dynamic_cast<Derv1*>(pUnknown))
        return true;
    else return false;
}
int main()
{
    Derv1 *d1=new Derv1;
    Derv2 *d2=new Derv2;
    
    if(isDerv1(d1))
        cout<<"d1 - object from class Derv1"<<endl;
    else
        cout<<"d1 - not object class Derv1"<<endl;
    if(isDerv1(d2))
        cout<<"d2 - object from class Derv1"<<endl;
    else
        cout<<"d2 - not object class Derv1"<<endl;
 
    system("pause");
    return 0;
}
Тут более менее все понятно.
Тогда вот, цитата:
"Операция в основном применятся для преобразования указателей родственных классов иерархии, в основном - указателя базового класса в указатель на производный..."
В главе "Изменение типов указателей с помощью dynamic_cast" (Лафоре) есть такое пример:
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
30
31
32
33
34
35
36
37
class Base
{
protected: 
    int ba;
public:
    Base() : ba(0)
    { }
    Base(int b) : ba(b)
    { }
    virtual void vertFunc()
    { }
    void show()
    { cout<<"Base: ba = "<<ba<<endl; }
};
class Derv : public Base
{ 
private:
    int da;
public:
    Derv(int b,int d) : Base(b), da(d)
    { }
    void show()
    { cout<<"Derv: ba = "<<ba<<" da = "<<da<<endl; }
};
 
int main()
{
    Base *pBase=new Base(10);
    Derv *pDerv=new Derv(21,22);
    pBase=dynamic_cast<Base*>(pDerv);
    pBase->show();
    pBase=new Derv(31,32);
    pDerv=dynamic_cast<Derv*>(pBase);
    pDerv->show();
    system("pause");
    return 0;
}
Зачем он тут вообще использует dynamic_cast? Я уже голову сломал.
0
26.07.2014, 14:03

Не по теме:

Цитата Сообщение от Tulosba Посмотреть сообщение
Не обязательно, особенно если тип ссылочный.
Я вообще-то говорил только про данный случай. Придираться тоже надо уметь :)

0
26.07.2014, 14:09

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Придираться тоже надо уметь
Вот это имелось в виду:
C++
1
dynamic_cast<Derived*>(bp)->info()

0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
26.07.2014, 14:12
Цитата Сообщение от stzer Посмотреть сообщение
Зачем он тут вообще использует dynamic_cast? Я уже голову сломал.
Обрати внимание, что у него функция show невиртуальная.

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

Не по теме:

Цитата Сообщение от Tulosba Посмотреть сообщение
dynamic_cast<Derived*>(bp)->info()
Да, я понял. Теперь ты пойми, я здесь не объяснял общие правила, а лишь сделал замечение по поводу того, что выражение с dynamic_cast у автора ни на что не влияет т.к. он не использует результат. Т.е. он полагал, что dynamic_cast изменяет свой аргумент.

1
 Аватар для stzer
140 / 110 / 60
Регистрация: 26.10.2013
Сообщений: 314
26.07.2014, 14:13  [ТС]
DrOffset, Хм,
А что происходит вот здесь
C++
1
pBase=dynamic_cast<Base*>(pDerv);
Объясни пожалуйста подробнейшим образом.
Просто если я в последнем листинге закомментирую строки с dynamic_cast это не повлияет на результат.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
26.07.2014, 14:25
Лучший ответ Сообщение было отмечено stzer как решение

Решение

Цитата Сообщение от stzer Посмотреть сообщение
А что происходит вот здесь
Приводит указатель на объект наследника к указателю на объект базовго класса, используя динамическую информацию о типах.
Вообще-то такое преобразование выполняется автоматическим и не требует dynamic_cast, т.к. класс наследника всегда знает своих родителей. В данном случае эффект будет эквивалентен вот этому:
C++
1
pBase = pDerv;
1
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
26.07.2014, 14:27
Глупость происходит. Вполне можно было написать
C++
1
pBase = pDerv;
dynamic_cast нужен для нисходящего, относительно иерархии наследования, приведения типов
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
26.07.2014, 14:29
C++
1
pBase=dynamic_cast<Base*>(pDerv);
Преобразование указателя на производный класс в указатель на базовый класс происходит неявно. Никакие касты тут не нужны. Можно просто:
C++
1
pBase = pDerv;
Но, видимо, для единообразия написали с dynamic_cast.
1
 Аватар для stzer
140 / 110 / 60
Регистрация: 26.10.2013
Сообщений: 314
26.07.2014, 14:29  [ТС]
DrOffset, Спасибо, походу что-то прояснилось.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
26.07.2014, 14:36
Цитата Сообщение от stzer Посмотреть сообщение
Просто если я в последнем листинге закомментирую строки с dynamic_cast это не повлияет на результат.
Потому что это код в main так составлен, возможно не очень наглядно. Посмотри, там изначально все указатели указывают на ожидаемые экземпляры, соответсвенно вывод не меняется. К тому же там ошибка, которая приводит к утечке памяти: pBase затирается (в первом dynamic_cast) другим значением и мы "теряем" указатель.

dynamic_cast очень редко когда действительно нужен и его использование в программе обычно говорит об ошибке проектирования.

Добавлено через 3 минуты
stzer, Вообще, вот из-за таких вот примеров поголовно все, кто по ним учился, начинают ассоциировать полиморфизм с new, что в общем-то неправильно.
0
 Аватар для stzer
140 / 110 / 60
Регистрация: 26.10.2013
Сообщений: 314
26.07.2014, 14:36  [ТС]
DrOffset, и еще тогда попутно
При использовании этого dynamic_cast<Derived*>(bp)->info()
вылетает ошибка. Как его использовать?

А по каким примерам учиться тогда?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
26.07.2014, 22:18
Цитата Сообщение от stzer Посмотреть сообщение
Как его использовать?
Значит в bp на самом деле не Derived. Возвращается ноль и вызов info приводит к ошибке. Надо проверять результат перед вызовом или использовать ссылочный вариант dynamic_cast<Derived&>(*bp), он генерирует исключение (std::bad_cast) при неправильном касте. Но исключение все равно надо где-то обрабатывать.

Добавлено через 7 часов 39 минут
Цитата Сообщение от stzer Посмотреть сообщение
А по каким примерам учиться тогда?
К сожалению нет таких книг, в которых бы совсем не было ошибок. Так что в сложившейся ситуации нужно просто проверять несколько источников, скажем одновременно несколько книг. Так хотя бы немного повысится вероятность, что информация не будет однобокой.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.07.2014, 22:18
Помогаю со студенческими работами здесь

НЕ могу разобраться в указателе
Помогите пожалуйста разобраться если у нас есть указатель на указатель например int **P указывает на массив указателей int *p т.е. **P...

не могу разобраться с typedef
помогите разобраться typedef задает синоним типа только? например: typedef int myint; тут понятно все, вместо int можно...

Не могу разобраться с файлами
помогите разобраться с файлами на Си, по примитиву, на премеро.

Не могу разобраться с ООП
Помогите разобраться с ошибками. Что не так делаю? public class Points { Points(double initial_x, double initial_y, double...

Не могу разобраться с gotoxy(y,x)
Вот мой код. Но дело в том, что gotoxy(y,x) выдает ошибку! ('gotoxy' is undefined). Библиотеку тоже подключил. Подскажите в чем проблема? ...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru