Должен ли я использовать reinterpret_cast C ++ поверх приведения в стиле C? - PullRequest
8 голосов
/ 08 декабря 2011

У меня есть следующая функция шаблона, используемая для выгрузки данных любого стандартного типа в двоичный поток вывода.

template<typename T> static void
dump ( const T& v, ostream& o ) {
    o.write ( reinterpret_cast<const char*>(&v), sizeof(T));
}

Вместо reinterpret_cast я мог бы также использовать стиль C (const char *). Есть ли особая причина для использования reinterpret_cast? Я прочитал несколько других постов, где reinterpret_cast был осужден. Но приведенное выше использование является законным и не может быть заменено чем-либо еще, верно?

Ответы [ 4 ]

14 голосов
/ 08 декабря 2011

Проблема с бросками C-Style в том, что они много делают под капотом. Смотрите подробное объяснение здесь: http://anteru.net/2007/12/18/200/

Вы должны стараться всегда использовать C ++ - приведение, облегчающее жизнь в долгосрочной перспективе. Основная проблема с приведением в стиле C в этом случае заключается в том, что вы могли бы написать (char*)(&v), тогда как с reinterpret_cast вам потребуется дополнительная const_cast, так что это немного безопаснее. Кроме того, вы можете легко найти reinterpret_cast с регулярным выражением, что невозможно для приведений в стиле C.

5 голосов
/ 08 декабря 2011

Разницы нет.В данной ситуации приведение в стиле C в точности повторяет интерпретацию.

Причина, по которой вы предпочитаете приведение в стиле C ++, заключается в том, что они явные относительно того, что они приводят.,Приведение в стиле C всегда будет пытаться использовать наиболее грубое приведение, если это необходимо, в то время как приведение в стиле C ++ компилируется, только если это возможно по назначению: статическое приведение выполняется только в том случае, если либо значения являются конвертируемыми, либо указатели / ссылкисовместимы, и приведение к действию работает только в том случае, если исходная и целевая версии являются cv-квалифицированными версиями друг друга.При повторном истолковании приведено явное заявление о том, что вы хотите проверить базовое двоичное представление.(Обратите внимание, что единственными действительными реинтерпретациями обычно являются те, от до указатель на пустоту или символ, если они не являются частью какой-то более крупной хитрости.)

3 голосов
/ 08 декабря 2011

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

dynamic_cast (expression) - разрешает приведение между надлежащей иерархией классов.

const_cast (выражение) - отбрасывает константу.

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

reinterpret_cast (выражение) - если требование все еще не выполнено, это доступно. Кастинг в стиле C, но с именем. Так что его будет легко найти в большой базе кода.

Примечание: - Большинство "reinterpret_cast" может быть устранено при правильном дизайне. Другими словами, «reinterpret_cast» необходим, значит, скорее всего, что-то не так в дизайне.

Обновление: Это должно быть последним вариантом, и в случае выше, использование является правильным. Теперь упоминание reinterpret_cast создаст у читателя впечатление, что автор намеренно решил не заботиться о безопасности типов. Но использование кастинга в стиле c не создаст такого впечатления.

1 голос
/ 08 декабря 2011

reinterpret_cast не одобряется, когда используется для замены static_cast или dynamic_cast.Рекомендуется использовать его для замены C-броска.

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

...