Когда следует использовать static_cast, dynamic_cast, const_cast и reinterpret_cast?

У меня была эта проблема с Firefox 36, также люди столкнулись с тем же, что и в 35 и 44.

Для вывода обновите свой Firefox до 37 или опустите его на что-либо меньшее, чем 33.

2314
задан user3728501 24 August 2015 в 13:58
поделиться

3 ответа

static_cast первый бросок, который необходимо попытаться использовать. Это делает вещи как неявные преобразования между типами (такой как int к float, или указатель на void*), и это может также назвать явные функции преобразования (или неявные). Во многих случаях явно утверждение static_cast не необходимо, но важно отметить, что T(something) синтаксис эквивалентен (T)something и должен избежаться (больше на этом позже). T(something, something_else) безопасно, однако, и гарантируемый вызвать конструктора.

static_cast может также бросить через иерархии наследования. Это является ненужным при кастинге вверх (к базовому классу), но когда кастинг вниз его может использоваться, пока это не бросает до virtual наследование. Это не делает проверки, однако, и это - неопределенное поведение к [1 110] вниз иерархия к типу, который не является на самом деле типом объекта.

<час>

const_cast может использоваться, чтобы удалить или добавить const к переменной; никакой другой бросок C++ не способен к удалению его (даже reinterpret_cast). Важно отметить, что, изменяя раньше const значение только не определено, если исходная переменная const; если Вы используете его для взятия const от ссылки на что-то, что не было объявлено с [1 117], это безопасно. Это может быть полезно при перегрузке функций членства на основе [1 118], например. Это может также использоваться для добавления const к объекту, например, для вызова перегрузки функции членства.

const_cast также работы так же над [1 121], хотя это менее распространено.

<час>

dynamic_cast исключительно используется для обработки полиморфизма. Можно бросить указатель, или ссылка на любой полиморфный тип к любому другому типу класса (полиморфный тип имеет по крайней мере одну виртуальную функцию, объявленную или наследованную). Можно использовать его для больше, чем просто кастинга вниз †“, можно бросить боком или сгладить другую цепочку. Эти dynamic_cast будет искать требуемый объект и возвращать его, если это возможно. Если это не может, это возвратиться nullptr в случае указателя или броска std::bad_cast в случае ссылки.

dynamic_cast имеет некоторые ограничения, все же. Это не работает, если существует несколько объектов того же типа в иерархии наследования (так называемый 'страшный ромб'), и Вы не используете virtual наследование. Это также может только пройти общедоступное наследование - это всегда не переместится до [1 128] или private наследование. Это редко - проблема, однако, формы как таковые наследования редки.

<час>

reinterpret_cast самый опасный бросок и должен использоваться очень экономно. Это поворачивает один тип непосредственно в другой —, такой как кастинг значения от одного указателя до другого или хранения указателя в int, или все виды других противных вещей. В основном единственная гарантия, которую Вы получаете с [1 132], - то, что обычно при кастинге результата назад к исходному типу Вы получите то же самое значение (но не , если промежуточный тип будет меньшим, чем исходный тип). Существует много преобразований, которые reinterpret_cast не могут сделать, также. Это используется, прежде всего, для особенно странных преобразований и побитовых обработок, как превращение потока необработанных данных в фактические данные или хранить данные в младших битах указателя на выровненные данные.

<час>

C-стиль бросил и , функциональный стиль бросил , броски, использующие (type)object или type(object), соответственно, и функционально эквивалентны. Они определяются как первое из следующего, которое успешно выполняется:

  • const_cast
  • static_cast (хотя игнорируя ограничения доступа)
  • static_cast (см. выше), тогда const_cast
  • reinterpret_cast
  • reinterpret_cast, тогда const_cast

Это может поэтому использоваться в качестве замены для других бросков в некоторых случаях, но может быть чрезвычайно опасно из-за способности опуститься до reinterpret_cast, и последний должен быть предпочтен, когда явный кастинг необходим, если Вы не уверены static_cast, успешно выполнится, или reinterpret_cast перестанет работать. Даже тогда рассмотрите дольше, более явная опция.

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

2419
ответ дан 24 revs, 18 users 67% 24 August 2015 в 13:58
поделиться

Используйте dynamic_cast для преобразования указателей/ссылок в иерархии наследования.

Использование static_cast для обычных преобразований типов.

Использование reinterpret_cast для иного толкования низкого уровня комбинаций двоичных разрядов. Используйте с экстремальной осторожностью.

Использование const_cast для того, чтобы выбросить const/volatile. Избегайте этого, если Вы не застреваете с помощью неправильного константой API.

310
ответ дан herohuyongtao 24 August 2015 в 13:58
поделиться

это отвечает на Ваш вопрос?

я никогда не использовал reinterpret_cast и задаюсь вопросом, не является ли столкновение со случаем, которому нужно оно, запахом плохого дизайна. В кодовой базе я работаю над dynamic_cast, используется много. Различие с static_cast - то, что dynamic_cast делает время выполнения, проверяющее, который может (более безопасный), или не может (больше служебное) быть тем, что Вы хотите (см. msdn).

14
ответ дан talnicolas 24 August 2015 в 13:58
поделиться
  • 1
    1) Нет у меня нет символьной ссылки на мой каталог медиа. 2) значения для self.location и имени:/home/tsoporan/site/media и /media/albums/anthem-for-the-underdog/30103635.jpg - (это для альбома, но проблемой является то же для художников или альбомов), 3) self.location isn' t пустой. 4) MEDIA_ROOT является все еще тем же, которому я верю. – tsoporan 23 December 2009 в 01:36
Другие вопросы по тегам:

Похожие вопросы: