Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
stzer
111 / 87 / 27
Регистрация: 26.10.2013
Сообщений: 270
Завершенные тесты: 2
#1

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

26.07.2014, 13:41. Просмотров 630. Ответов 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)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.07.2014, 13:41
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Не могу разобраться с dynamic_cast (C++):

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

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

Не могу разобраться с программой в С++ - C++
Написала программку на С++, он ее запускает и как я понимаю выполняет, но вот результатов я не вижу( И вот что мне выдает сама программа: ...

не могу разобраться в программе - C++
Здравствуйте! Программа сортирует методом пузырька числа с плавающей точкой,которые находятся в файле Input.txt Помогите пожалуйста...

Не могу разобраться со строками - C++
Вот задание: Напишите программу поиска в строке знаков пунктуации. Программа должна позволить ввести символьную строку, содержащую знаки...

не могу разобраться с вектором - C++
Доброй ночи. Никак не пойму почему не работает. Есть 3 файла 3.cpp #include &lt;stdio.h&gt; #include &quot;lib/simply.h&quot; int main(void)...

14
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
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
Tulosba
:)
Эксперт С++
4705 / 3240 / 297
Регистрация: 19.02.2013
Сообщений: 9,046
26.07.2014, 13:59 #3
Цитата Сообщение от DrOffset Посмотреть сообщение
Во-первых, результат dynamic_cast нужно чему-то присвоить.
Не обязательно, особенно если тип ссылочный.
stzer, чтобы получить вывод характерный для производного класса указатель должен указывать на объект этого (производного) класса.
Т.е. в первом приближении достаточно добавить:
C++
1
bp=&derived;
0
stzer
111 / 87 / 27
Регистрация: 26.10.2013
Сообщений: 270
Завершенные тесты: 2
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
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
26.07.2014, 14:12 #7
Цитата Сообщение от stzer Посмотреть сообщение
Зачем он тут вообще использует dynamic_cast? Я уже голову сломал.
Обрати внимание, что у него функция show невиртуальная.

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

Не по теме:

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

1
stzer
111 / 87 / 27
Регистрация: 26.10.2013
Сообщений: 270
Завершенные тесты: 2
26.07.2014, 14:13  [ТС] #8
DrOffset, Хм,
А что происходит вот здесь
C++
1
pBase=dynamic_cast<Base*>(pDerv);
Объясни пожалуйста подробнейшим образом.
Просто если я в последнем листинге закомментирую строки с dynamic_cast это не повлияет на результат.
0
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
26.07.2014, 14:25 #9
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от stzer Посмотреть сообщение
А что происходит вот здесь
Приводит указатель на объект наследника к указателю на объект базовго класса, используя динамическую информацию о типах.
Вообще-то такое преобразование выполняется автоматическим и не требует dynamic_cast, т.к. класс наследника всегда знает своих родителей. В данном случае эффект будет эквивалентен вот этому:
C++
1
pBase = pDerv;
1
Toshkarik
1148 / 865 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
26.07.2014, 14:27 #10
Глупость происходит. Вполне можно было написать
C++
1
pBase = pDerv;
dynamic_cast нужен для нисходящего, относительно иерархии наследования, приведения типов
0
Tulosba
:)
Эксперт С++
4705 / 3240 / 297
Регистрация: 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
stzer
111 / 87 / 27
Регистрация: 26.10.2013
Сообщений: 270
Завершенные тесты: 2
26.07.2014, 14:29  [ТС] #12
DrOffset, Спасибо, походу что-то прояснилось.
0
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
26.07.2014, 14:36 #13
Цитата Сообщение от stzer Посмотреть сообщение
Просто если я в последнем листинге закомментирую строки с dynamic_cast это не повлияет на результат.
Потому что это код в main так составлен, возможно не очень наглядно. Посмотри, там изначально все указатели указывают на ожидаемые экземпляры, соответсвенно вывод не меняется. К тому же там ошибка, которая приводит к утечке памяти: pBase затирается (в первом dynamic_cast) другим значением и мы "теряем" указатель.

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

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

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

Добавлено через 7 часов 39 минут
Цитата Сообщение от stzer Посмотреть сообщение
А по каким примерам учиться тогда?
К сожалению нет таких книг, в которых бы совсем не было ошибок. Так что в сложившейся ситуации нужно просто проверять несколько источников, скажем одновременно несколько книг. Так хотя бы немного повысится вероятность, что информация не будет однобокой.
1
26.07.2014, 22:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.07.2014, 22:18
Привет! Вот еще темы с ответами:

Не могу разобраться с регуляркой C++ - C++
Привет всем, помогите кто знает, у меня есть строка: string str=&quot;NUM 16093.99 /NUMBER ... /NUMBER /NUMBER&quot;; Возможно ли как то,...

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

не могу разобраться с синтаксисом - C++
известен код программы, но не могу разобраться что к чему. если не трудно объясните что означает каждая строчка. заранее спасибо. ...

Не могу разобраться с циклом - C++
int _tmain(int argc, _TCHAR* argv) { int x,y; cout &lt;&lt; &quot;Vvedite dva chisla&quot; &lt;&lt; endl; cin &gt;&gt; x &gt;&gt; y; for (int i=1; i&lt;=y; i++) { ...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru