134 / 104 / 60
Регистрация: 26.10.2013
Сообщений: 312
1

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

26.07.2014, 13:41. Показов 885. Ответов 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)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.07.2014, 13:41
Ответы с готовыми решениями:

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

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

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

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

14
17415 / 9249 / 2262
Регистрация: 30.01.2014
Сообщений: 16,196
26.07.2014, 13:59 2
Цитата Сообщение от 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 3
Цитата Сообщение от DrOffset Посмотреть сообщение
Во-первых, результат dynamic_cast нужно чему-то присвоить.
Не обязательно, особенно если тип ссылочный.
stzer, чтобы получить вывод характерный для производного класса указатель должен указывать на объект этого (производного) класса.
Т.е. в первом приближении достаточно добавить:
C++
1
bp=&derived;
0
134 / 104 / 60
Регистрация: 26.10.2013
Сообщений: 312
26.07.2014, 14:00  [ТС] 4
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
DrOffset
26.07.2014, 14:03
  #5

Не по теме:

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

0
Tulosba
26.07.2014, 14:09
  #6

Не по теме:

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

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

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

Не по теме:

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

1
134 / 104 / 60
Регистрация: 26.10.2013
Сообщений: 312
26.07.2014, 14:13  [ТС] 8
DrOffset, Хм,
А что происходит вот здесь
C++
1
pBase=dynamic_cast<Base*>(pDerv);
Объясни пожалуйста подробнейшим образом.
Просто если я в последнем листинге закомментирую строки с dynamic_cast это не повлияет на результат.
0
17415 / 9249 / 2262
Регистрация: 30.01.2014
Сообщений: 16,196
26.07.2014, 14:25 9
Лучший ответ Сообщение было отмечено stzer как решение

Решение

Цитата Сообщение от stzer Посмотреть сообщение
А что происходит вот здесь
Приводит указатель на объект наследника к указателю на объект базовго класса, используя динамическую информацию о типах.
Вообще-то такое преобразование выполняется автоматическим и не требует dynamic_cast, т.к. класс наследника всегда знает своих родителей. В данном случае эффект будет эквивалентен вот этому:
C++
1
pBase = pDerv;
1
1180 / 893 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
26.07.2014, 14:27 10
Глупость происходит. Вполне можно было написать
C++
1
pBase = pDerv;
dynamic_cast нужен для нисходящего, относительно иерархии наследования, приведения типов
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
26.07.2014, 14:29 11
C++
1
pBase=dynamic_cast<Base*>(pDerv);
Преобразование указателя на производный класс в указатель на базовый класс происходит неявно. Никакие касты тут не нужны. Можно просто:
C++
1
pBase = pDerv;
Но, видимо, для единообразия написали с dynamic_cast.
1
134 / 104 / 60
Регистрация: 26.10.2013
Сообщений: 312
26.07.2014, 14:29  [ТС] 12
DrOffset, Спасибо, походу что-то прояснилось.
0
17415 / 9249 / 2262
Регистрация: 30.01.2014
Сообщений: 16,196
26.07.2014, 14:36 13
Цитата Сообщение от stzer Посмотреть сообщение
Просто если я в последнем листинге закомментирую строки с dynamic_cast это не повлияет на результат.
Потому что это код в main так составлен, возможно не очень наглядно. Посмотри, там изначально все указатели указывают на ожидаемые экземпляры, соответсвенно вывод не меняется. К тому же там ошибка, которая приводит к утечке памяти: pBase затирается (в первом dynamic_cast) другим значением и мы "теряем" указатель.

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

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

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

Добавлено через 7 часов 39 минут
Цитата Сообщение от stzer Посмотреть сообщение
А по каким примерам учиться тогда?
К сожалению нет таких книг, в которых бы совсем не было ошибок. Так что в сложившейся ситуации нужно просто проверять несколько источников, скажем одновременно несколько книг. Так хотя бы немного повысится вероятность, что информация не будет однобокой.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.07.2014, 22:18
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru