Ответы:
Во-первых, поймите, что эти строки не эквивалентны .
int* anInt = (int*)aFloat; // is equivalent to
int* anInt = reinterpret_cast<int*>(aFloat);
Здесь происходит то, что программист просит компилятор сделать все возможное, чтобы выполнить приведение.
Разница важна, потому что использование static_cast будет запрашивать только базовый тип, в который «безопасно» конвертировать, где reinterpret_cast будет конвертировать во что угодно, возможно, просто отображая требуемый макет памяти в памяти данного объекта.
Таким образом, поскольку «фильтр» не тот же, использование конкретного приведения является более понятным и безопасным, чем использование C-преобразования, если вы полагаетесь на компилятор (или во время выполнения, если вы используете dynamic_cast), чтобы сказать вам, где вы сделали что-то не так , избегая C cast и reinterepret_cast.
Теперь, когда это стало более понятным, появилась другая вещь: static_cast, reinterpret_cast, const_cast и dynamic_cast легче искать .
И конечная точка: они безобразны . Вот и хотел. Потенциально глючный код, запахи кода, очевидные «уловки», которые могут генерировать ошибки, легче отследить, когда он связан с уродливым внешним видом. Плохой код должен быть безобразным .
Это "по замыслу". И это позволяет разработчику знать, где он мог бы сделать что-то лучше (полностью избегая приведений, если в этом нет особой необходимости) и где это хорошо, но это «документировано» в коде, «пометив» его как некрасивое.
Вторичной причиной введения нового стиля было то, что броски в стиле C очень трудно обнаружить в программе. Например, вы не можете удобно искать приведения, используя обычный редактор или текстовый процессор. Эта почти невидимость бросков в стиле С особенно прискорбна, потому что они потенциально опасны. Уродливая операция должна иметь уродливую синтаксическую форму. Это наблюдение было одной из причин выбора синтаксиса приведений нового стиля. Еще одна причина заключалась в том, что приведения в новом стиле соответствовали нотации шаблона, чтобы программисты могли писать свои собственные приведения, особенно при проверке во время выполнения.
Может быть, из-за того, что static_cast настолько уродлив и относительно труден для ввода, вы, скорее всего, дважды подумаете, прежде чем его использовать? Это было бы хорошо, потому что в современном C ++ приведение действительно можно избежать.
Приведение C ++ более ограничено (поэтому лучше выражайте свои намерения, упростите проверку кода и т. Д.). Их также намного легче искать, если вам когда-либо понадобится.
Вариант C: приведение типа "C ++", потому что оно неотличимо от конструкции:
int anInt = int(aFloat);
или даже:
int anInt(aFloat);
Кроме этого, кроме этих тривиальных случаев с примитивами, которые хорошо понятны, я предпочитаю использовать x_cast <> вместо приведений в стиле C. Есть три причины, почему:
Они более узко определяют операцию, которую пытался выполнить программист.
Они могут выполнять действия, которые не могут выполняться в стиле C (особенно в случае dynamic_cast <>, который может выполнять перекрестное приведение через ветви цепочки множественного наследования).
Они безобразны . Они громко заявляют, что программист работает против системы типов. В этом случае это хорошая вещь.
Если вы пишете код на C, используйте C cast. При написании на C ++ используйте приведение C ++.
В то время как большинство приведений нарушает правильную безопасность типов, классы C ++ более строгие, и поэтому вы немного менее небезопасны по сравнению с типом C.
Я могу допустить, чтобы кто-то использовал (T *) NULL, хотя для принудительной перегрузки ...
У меня есть несколько правил о приведениях в стиле C / C ++:
const_cast
. По понятным причинам. К сожалению, мое правило об отмене применения const, заставляющего клавиатуру подниматься и ломать палец программиста, не было одобрено.reinterpret_cast
. Это действительно тот тип приведения, которого нет у C: притвориться, что биты этого целого числа на самом деле являются битами с плавающей точкой. Это позволяет избежать неприятностей, как (int)(*(int*)(&floatVar))
.dynamic_cast
», остановите и заново оцените вашу полиморфную иерархию классов и дизайн. Продолжайте переоценку дизайна иерархии классов, пока не сможете удалить эти слова.static_cast
.Причина № 4 в том, что это не имеет значения. Обстоятельства, которые не вписываются в другие правила, либо очевидны, либо действительно низкоуровневы. Хорошо понятное преобразование простых типов, таких как int-to-float, не должно нуждаться в специальном синтаксисе. И если вы в глубоких, уродливых кишках чего-то, ну, вы в глубоких, уродливых кишках чего-то. Нет необходимости привлекать внимание к тому факту, что «здесь будут драконы», поскольку зубы, когти и огонь в значительной степени уже отдали его.
dynamic_cast
это совершенно правильный инструмент. Я признаю, что это очень полезно, но это далеко от сатаны таких вещей, как глобальные переменные. Тем не менее, в первую очередь, я проголосовал против вас, потому что вы не ответили на вопрос , касающийся использования или не приведений типа C.
Как отмечают вышеприведенные посты, приведение C ++ (статическое) на практике немного безопаснее.
Было бы разумно найти дополнительную информацию о различных видах кастинга и их плюсах и минусах.
Просто чтобы узнать больше о том, почему. ,
http://en.wikipedia.org/wiki/Static_cast
Это действительно зависит от того, с каким языком я работаю, так как вы знаете, что они говорят: в Риме говорят по-римски. Поэтому, если я программирую на C, я стараюсь максимально использовать возможности C, но если я программирую на C ++, я продолжаю и максимально использую возможности C ++, даже если некоторым людям не нравится такой подход, потому что говорят, что это делает код «менее переносимым», я говорю, что мне все равно, я на C ++ и программирую на C ++, и мне нужен полностью совместимый с C ++ компилятор для компиляции кода, иначе я бы работал с чем-то другим на первом месте.
static_cast и т. д. были изобретены из-за проблем с приведением стиля C при использовании в шаблонах. Если вы пишете шаблон, или если ваш код может быть позже преобразован в шаблон, рекомендуется использовать приведение в стиле C ++. Причина в том, что приведения в стиле C ++ лучше выражают намерения, поэтому они дадут ожидаемые результаты в тех случаях, когда приведения в стиле C будут выполнять неправильные действия (учитывая конкретные типы в качестве параметров шаблона).
Кроме этого, я говорю, используйте приведение в стиле C ++, если у вас есть специфическая проблема, которая нуждается в них - dynamic_cast является наиболее распространенным, но даже это, вероятно, не каждый день.
Что-нибудь еще, и приведение стиля C может быть немного меньше беспорядка и помочь читаемости, или возможно не в зависимости от того, насколько читатель знаком с этим стилем броска в эти дни. Это не очень важно, на мой взгляд, в основном из личных предпочтений, хотя не удивляйтесь, если некоторым людям не понравится стиль C.
Последнее замечание - если вам нужно так много разыгрываний, что это большое дело, вы, вероятно, делаете что-то еще неправильно. В некоторых случаях есть исключения из этого, но большинству высокоуровневого кода не нужно много (если есть) приведений.
reinterpret_cast<int>(double);
. Полностью возможно привести к двойному типу int с приведением в стиле c, но это не возможно сделать с reinterpret_cast. Я вижу, Тимбо уже указал вам на это, и вы сказали, что исправите это, но четыре года спустя это остается неверным. Тем не менее, я бы все равно понизил голос, если бы это было исправлено, поскольку есть совершенно веские причины, по которым нужно использовать приведение. Вот лучший ответ: stackoverflow.com/a/332086/3878168