Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.61/181: Рейтинг темы: голосов - 181, средняя оценка - 4.61
 Аватар для Mar-12
-21 / 5 / 3
Регистрация: 14.03.2013
Сообщений: 130

Чем отличаются dynamic_cast и static_cast?

15.06.2013, 16:19. Показов 37194. Ответов 21
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
если можно пример напишите
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.06.2013, 16:19
Ответы с готовыми решениями:

Отличия dynamic_cast, static_cast и (object*)
хочу разобраться с преобразованием указателей в c++ Итак имеем указатель на какойто класс myclass *mc = new myclass(); ...

Dynamic_cast и static_cast: в чём смысл?
Здравствуйте! Подскажите пожалуйста... В теории, как я понял, dynamic_cast является лишь приравниванием ссылки на 1 класс(допустим,...

Когда использовать static_cast и dynamic_cast?
Всем добрый день! Такой вопрос - назревает у меня собеседование, и есть ряд вопросов, которые срочно нужно подтянуть. Один из них,...

21
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
15.06.2013, 16:59
dynamic_cast - каст с проверкой, а возможен ли такой каст. если нет - будет или исключение или результат каста - нуль. static_cast - без проверок.
0
 Аватар для Desu_Is_A_Lie
216 / 63 / 16
Регистрация: 26.02.2012
Сообщений: 114
15.06.2013, 17:00
Плюс dynamic требует RTTI.
0
40 / 37 / 15
Регистрация: 25.10.2012
Сообщений: 112
15.06.2013, 17:06
static_cast - это приведение типа по обычным правилам. От C-style приведения отличается тем, что запрещает приведение одного указателя на произвольный тип к другому, за исключением приведения нетипизированных указателей и приведения вниз по иерархии классов (downcast).
C++ (Qt)
1
2
3
4
5
6
int i = -1; 
long j = static_cast<long>( i); // OK
 
A a;
void* ptr = &a;
A* aPtr = static_cast<A*>( ptr); // OK
reinterpret_cast также выполняет преобразование от одного типа к другому, но использует механизм RTTI, чтобы проверить, является ли приводимый объект объектом типа приведения. Если это условие не выполнено, то для указателей возвращается NULL, а для ссылок генерируется исключение std::bad_cast.
2
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
15.06.2013, 18:53
Лучший ответ Сообщение было отмечено как решение

Решение

static_cast выполняет проверку на этапе компиляции.
Если типы несовместимые, компиляция завершается с ошибкой.

dynamic_cast выполняет проверку на этапе выполнения и зависит от механизма
динамической информации о типах (RTTI), поэтому его использование влечет за
собой некоторые накладные расходы. Если типы несовместимые, dynamic_cast бросает
исключение std::bad_cast (для ссылок) или возвращает NULL (для указателей).

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

Основное назначение dynamic_cast - защита от нисходящего приведения типов в тех
случаях, когда это лишено смысла. Например, если у вас есть ссылка или указатель
на базовый класс, но вы точно знаете, что на самом деле она указывает на экземпляр
производного типа, вы можете выполнить приведение и работать с производным типом.
Это называется нисходящее приведение. Но если там будет объект базового типа,
лишенный своей производной части, такое приведение лишено смысла и приведет к
неопределенному поведению.

Ни static_cast, ни тем более приведение в стиле C такую ситуацию не ловят.
А 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
38
39
40
41
42
43
44
45
46
47
#include <iostream>
 
 
 
class abc
{
public:
    virtual ~abc() {}
};
 
 
 
class def : public abc
{
public:
    ~def() {}
};
 
 
 
template <typename T_TypeTo, typename T_TypeFrom>
void test_casting(T_TypeFrom *p)
{
    std::cout << std::boolalpha << (NULL != dynamic_cast<T_TypeTo>(p)) << std::endl;
}
 
 
 
int main()
{
    abc *pAbc    = new abc();
    def *pDef    = new def();
    abc *pAbcDef = new def();
 
    test_casting<abc *>(pAbc);
    test_casting<abc *>(pDef);
    test_casting<abc *>(pAbcDef);
    test_casting<def *>(pAbc);
    test_casting<def *>(pDef);
    test_casting<def *>(pAbcDef);
 
    delete pAbcDef;
    delete pDef;
    delete pAbc;
 
    return 0;
}
Вывод:
true
true
true
false
true
true
15
 Аватар для Mar-12
-21 / 5 / 3
Регистрация: 14.03.2013
Сообщений: 130
15.06.2013, 19:36  [ТС]
Убежденный, у меня есть классы Parent<---Child1,Parent<---Child2;
C++
1
2
3
4
virtual void Method(Parent* a)
    {
        Child1 object=static_cast<Child1*>(a);
    }
предположим что a это
C++
1
Parent* a=new Child2();
Как будет работать static_cast ?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
15.06.2013, 19:56
static_cast выполняется на этапе компиляции, из-за этого он в принципе не может
знать, объект какого типа будет передан в функцию на этапе выполнения программы.
Поэтому Parent будет в любом случае приведен к Child, даже если вы создадите
его вот так:
C++
1
Parent *a = new Parent();
0
 Аватар для Mar-12
-21 / 5 / 3
Регистрация: 14.03.2013
Сообщений: 130
15.06.2013, 20:00  [ТС]
Убежденный, тогда будет не тот результат которого я ожидала,вроде поняла,спасибо
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
22.11.2013, 10:15
Цитата Сообщение от Убежденный Посмотреть сообщение
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
#include <iostream>
 
template <class To, class From>
void cast( From* f )
{
    std::cout << std::boolalpha << (nullptr != dynamic_cast<To>(f)) << std::endl;
}
 
class B
{
public:
    virtual ~B() {}
};
 
class D : protected B 
{
public:
    void f() 
    { 
        B* b = new D(); // ОК
        cast<D*>(b); // true только для public наследования, но компилируется независимо от типа наследования
    }
};
 
int main() {
    
    D d;
    
    // B* b = new D(); // Ошибка компиляции если не public наследование
    
    d.f();
 
    return 0;
}
2
Заблокирован
22.11.2013, 11:02
лично по мне, на много проще, прозрачней и удобней приводить типы по старинке, просто в скобках писать приведение да и всё, типа int a = (int)b;
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
22.11.2013, 11:13
newbie666, Вы вкурсе, что это практически эквивалентно reintrepret_cast, который в С++ использовать вообще не стоит (или стоит крайне редко)?
0
Заблокирован
22.11.2013, 11:18
Цитата Сообщение от ForEveR Посмотреть сообщение
Вы вкурсе, что это практически эквивалентно reintrepret_cast
да, но согласитесь, (int) намного короче строчка, чем reintrepret_cast. Эти длинные не удобные названия и делали для того, чтоб меньше типы приводили )))
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
22.11.2013, 11:18
newbie666, Но менее типо-безопасно. Хуже искать по тексту. И прочее-прочее-прочее.
0
Заблокирован
22.11.2013, 11:20
не вижу ни какого смысла, вот реально, ни какого профита, использовать эти длинные в плане букв приведения, вместо простых типов в скобках , как по старинке

Добавлено через 1 минуту
Цитата Сообщение от ForEveR Посмотреть сообщение
Но менее типо-безопасно
ааа безопасность - лозунг нового стандарта... Я всю эту безопасность отрубаю сразу, все эти ерроры , которые раньше были варнингами и тд... Надо полагаться на собственную голову
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
22.11.2013, 11:22

Не по теме:

Вот интересно, тема про static vs dynamic, а скатились в reinterpret. Давайте const_cast еще вспомним :)


Цитата Сообщение от newbie666 Посмотреть сообщение
чтоб меньше типы приводили
Чем меньше явных приведений типов, тем лучше код. Имхо.

Добавлено через 1 минуту
Цитата Сообщение от newbie666 Посмотреть сообщение
Надо полагаться на собственную голову
"Голова не чердак для хлама" (с) Шерлок Холмс
0
Заблокирован
22.11.2013, 11:24
Цитата Сообщение от Tulosba Посмотреть сообщение
Голова не чердак для хлама
согласен.. ладно...проехали, лучше гляньте мой топик на winapi, может идеи есть у кого
0
0 / 0 / 0
Регистрация: 21.01.2016
Сообщений: 24
01.01.2017, 23:18
Есть вопрос. Что если имеется несколько функций с одним именем, но разными параметрами, естественно. Как передать нужную в алгоритм for_each в качестве третьего параметра?
static_cast<тип нужной функции>(имя функции)
А что считать "типом нужной функции"?

Конкретнее: это нужно для функции gl::vertex
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.01.2017, 00:46
Цитата Сообщение от DieToday Посмотреть сообщение
А что считать "типом нужной функции"?
тип нужной функции.
0
0 / 0 / 0
Регистрация: 21.01.2016
Сообщений: 24
02.01.2017, 01:15
hoggy, черт, это вы так посты себе набиваете?
Все перегрузки функции gl::vertex, о которой я говорю выше, имеют тип void.
Вопрос всё ещё открыт: как передать нужную функцию в алгоритм в качестве параметра, использую static_cast?
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
02.01.2017, 02:34
Цитата Сообщение от DieToday Посмотреть сообщение
Вопрос всё ещё открыт: как передать нужную функцию в алгоритм в качестве параметра, использую static_cast?
Уточнения сигнатуры функции для std::function
Уточнения сигнатуры функции для std::function

Добавлено через 1 минуту
Цитата Сообщение от DieToday Посмотреть сообщение
Все перегрузки функции gl::vertex, о которой я говорю выше, имеют тип void.
Это не так. Тип void - это тип возвращаемого значения функции, а не тип функции. Тип функции, образно говоря, - это сама функция.
Вот функция:
C++
1
void foo(int i, char c);
Вот ее тип:
C++
1
void (int i, char c)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.01.2017, 02:34
Помогаю со студенческими работами здесь

Теряются ли данные при использовании static_cast и dynamic_cast?
Здравствуйте! Подскажите пожалуйста, при преобразовании данными методами производного класса к базовому, происходит же потеря данных?...

Чем отличается static_cast от приведения в стиле Си?
Привет всем! чем отличаются явное приведения типа long tmp = static_cast&lt;long&gt;(45.6); от long tmp = long(54.34); ?

В чем разница между Си'шным приведением типа и унарной шаблонной функцией static_cast?
В чем разница между Си'шным приведением типа: ... int x{5}; ifs.write( (char*)&amp;x, sizeof(int) ); ... и унарной шаблонной...

Чем отличаются компиляторы?
Здравствуйте. 32-bit / 64-bit -- Понятно. Чем отличается threads-win32 от threads-posix, dwarf от sjlj?

Чем отличаются операторы while и for?
Добрый вечер, чем отличается while от for, в каких случаях нужно использовать while а в каких for?


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru