Похоже, что static_cast и reinterpret_cast работают нормально для приведения void * к другому типу указателя. Есть ли веская причина отдать предпочтение одному над другим?
202
Похоже, что static_cast и reinterpret_cast работают нормально для приведения void * к другому типу указателя. Есть ли веская причина отдать предпочтение одному над другим?
Ответы:
Использование
static_cast
: это самый узкий состав, который точно описывает, какое преобразование сделано здесь.Существует заблуждение, что использование
reinterpret_cast
будет лучшим совпадением, потому что это означает «полностью игнорировать безопасность типов и просто приводить от А к В».Тем не менее, это на самом деле не описывает эффект
reinterpret_cast
. Скорее,reinterpret_cast
имеет ряд значений, для всех из которых утверждается, что «выполняемое отображение определяетсяreinterpret_cast
реализацией». [5.2.10.3]Но в частном случае приведение
void*
кT*
отображению полностью определено стандартом; а именно, назначить тип указателю без указания типа без изменения его адреса.Это причина для предпочтения
static_cast
.Кроме того, и, возможно, более важным является тот факт, что любое использование
reinterpret_cast
является совершенно опасным, потому что оно преобразует что-либо во что-либо действительно (для указателей), в то время какstatic_cast
это намного более ограничительно, обеспечивая тем самым лучший уровень защиты. Это уже спасло меня от ошибок, когда я случайно попытался привести один тип указателя к другому.источник
Это сложный вопрос. С одной стороны, Конрад делает отличное замечание относительно определения спецификации для reinterpret_cast , хотя на практике это, вероятно, делает то же самое. С другой стороны, если вы преобразуете между типами указателей (как это обычно бывает при индексировании в памяти через char *, например), static_cast сгенерирует ошибку компилятора, и вы все равно будете вынуждены использовать reinterpret_cast .
На практике я использую reinterpret_cast, потому что он более наглядно описывает цель операции приведения. Можно, конечно, сделать так, чтобы другой оператор назначил только реинтерпретации указателя (что гарантировало возвращение того же адреса), но в стандарте его нет.
источник
reinterpret_cast
!Я предлагаю всегда использовать самый слабый актерский состав.
reinterpret_cast
может использоваться для приведения указателя кfloat
. Чем сильнее разрушается структура актерского состава, тем больше внимания требует его использование.В случае
char*
я бы использовал приведение в стиле c, пока у нас их не будетreinterpret_pointer_cast
, потому что оно слабее и ничего другого недостаточно.источник
float f = *reinterpret_cast<const float*>(&p);
float
, что неверно. Выражение приводитсяvoid **
кconst float *
, а затем использует операцию разыменования (которая НЕ является приведением) для преобразованияconst float *
вfloat
.Мои личные предпочтения основаны на грамотности кода:
или
Они оба делают то же самое в конце, но static_cast кажется более подходящим в промежуточном ПО, среде приложения, в то время как переосмысление приведено больше как то, что вы видели бы в низкоуровневой библиотеке IMHO.
источник