#cpp
Если мы используем reinterpret_cast для приведения указателя к указателю, объекта к указателю или указателя к объекту, то приведение осуществляется корректно. int n = 0; char* c = reinterpret_cast(n); int another_value = reinterpret_cast (c); Почему reinterpret_cast не позволяет осуществлять приведение на простых форматах? Такой код не собирается: int a = 0; char b = reinterpret_cast (a); по Страуструпу: reinterpret_cast управляет преобразованиями между несвязанными типами, например целых в указатели или указателей в другие(несвязанные) указатели. по Майерсу: reinterpret_cast предназначен для низкоуровневых приведений, которые порождают зависимые от реализации (то есть непереносимые) результаты, например приведение указателя к int. Итак, и указатель к указателю, и указатель к int, и int к указателю посредством reinterpret_cast приводятся. Алена Л. в блоге пишет: reinterpret_cast - самое нахальное приведение типов. Не портируемо, результат может быть некорректным, никаких проверок не делается. Считается, что вы лучше компилятора знаете как на самом деле обстоят дела, а он тихо подчиняется. Не может быть приведено одно значение к другому значению. Обычно используется, чтобы привести указатель к указателю, указатель к целому, целое к указателю. Умеет также работать со ссылками. Хорошо, одно значение к другому не может быть приведено. Почему эту возможность не запилили?
Ответы
Ответ 1
reinterpret_cast, как видно из названия, предназначен в первую очередь для выполнения переинтерпретации памяти. То есть когда вы приводите указатель типа T * к указателю типа U *, то предполагается, что вы это делаете для того, чтобы обратиться к памяти исходного объекта типа T, как к памяти объекта типа U. В этом и заключается переинтерпретации памяти. (Разумеется, легальность такого доступа зависит еще от массы посторонних факторов.) reinterpret_cast также поддерживает аналог такого указательного преобразования, но в варианте со ссылками вместо указателей, т.е. вы можете сделать T t; U &u = reinterpret_cast(t); и далее получать доступ к памяти объекта t как объекта типа U. Также на reinterpret_cast дополнительно "повесили" побочную функциональность - приведение между указательными и целыми типами. Все. А вот чего вы хотели добиться, выполняя reinterpret_cast типа int к типу char - не ясно. Если вам нужна именно переинтерпретация памяти, то это делается так int a = 0; char b = reinterpret_cast(a); то есть целевой тип должен быть ссылкой. Ваш же вариант выглядит как обычное преобразование типов, выполняемое static_cast, а не reinterpret_cast. Вся идея разнообразия типов кастов в С++ как раз и сводится к разделению обязанностей между ними с минимальными пересечениями. Ответ 2
Смотрите. Преобразования бывают двух типов: меняющие внутреннее представление, и не меняющие его. Преобразование int в double меняет внутреннее представление, double имеет хитрый бинарный layout с мантиссой и порядком. Преобразование целочисленных типов тоже меняет внутреннее представление, если у них разные длины. А вот смысл reinterpret_cast, наоборот, в том, что он меняет тип объекта с точки зрения компилятора, и (кроме возможных патологических компиляторов) никак не отображается в объектном коде. Вы ж помните, что объект — это просто набор бит в памяти и его тип, позволяющий интерпретировать его? reinterpret_cast просто просит компилятор интерпретировать его по-другому, не меняя сами биты в памяти. А преобразование, которое умеет делать всё, преобразовывать и числовые типы, и указатели, уже запилили. Это C-style cast. Правда, из-за избыточной мощи его использование не рекомендуется — именно потому, что он может и числа преобразовать, и указатели, и вашего кота, даже если вы этого и не хотели.
Комментариев нет:
Отправить комментарий