2016-09-22 12 views
1

Я знаю, что reinterpret_cast в основном используется для использования или из char*.Почему я могу использовать static_cast С void *, но не с char *

Но я с удивлением обнаружил, что static_cast может сделать то же самое с void*. Например:

auto foo "hello world"s; 
auto temp = static_cast<void*>(&foo); 
auto bar = static_cast<string*>(temp); 

Что мы получаем от использования reinterpret_cast и char* над static_cast и void*? Это как-то связано со строгой проблемой псевдонимов?

+1

Как правило, вы производите символ 'char *', чтобы сделать что-то с отдельными байтами. Вы не можете сделать это с помощью 'void *'. – NathanOliver

+0

@NathanOliver Итак, вы говорите как «memcpy» или подобное? –

+1

Ну, «memcpy» - один из них. Функция 'read' и' wrtie' потоков - это другие. Если вам нужно отправить материал поверх данных com, вы также сделаете это. – NathanOliver

ответ

0

Ваш вопрос действительно имеет 2-х частей:

  1. Должен ли я использовать static_cast или reinterpret_cast работать с указателем на подстилающей битов объекта, не заботясь о типе объекта?
  2. Если я должен использовать reinterpret_cast, то есть void* или char* предпочтительнее адресовать этот базовый шаблон бита?

static_cast: Преобразование между типами, используя комбинацию неявных и определенных пользователем преобразований

В 5.2.9 [expr.static.cast] 13 стандартного, на самом деле, приводит пример :

T* p1 = new T; 
const T* p2 = static_cast<const T*>(static_cast<void*>(p1)); 

Он использует неявное приведение:

Указатель prvalue для любого (необязательно cv-квалифицированного) типа объекта T может быть преобразован в указатель prvalue (идентично с квалификацией cv) void. Результирующий указатель представляет то же место в памяти, что и исходное значение указателя.Если исходный указатель является значением нулевого указателя, результатом является значение нулевого указателя для типа назначения. *

Там нет, однако, не неявное приведение из указателя типа T к char*. Таким образом, единственный способ выполнить этот бросок - с reinterpret_cast.

reinterpret_cast: Преобразование между типами по переинтерпретации основной битовый шаблон

Таким образом, в ответ на части ваш вопрос, когда вы приводите к void* или char* вы хотите работать с базовый бит-шаблон, reinterpret_cast следует использовать, потому что его использование означает, что читатель преобразует в/из базового шаблона бита.

Дальше сравните void* по char*. Решение между этими двумя может быть более зависимым от приложения. Если вы собираетесь использовать стандартную библиотечную функцию с подстилающими битами просто использовать тот тип, который функция принимает:

  • void* используется в mem функциях, предусмотренных в cstring библиотеке
  • read и write использование char* как Входы

Примечательно, что для конкретных объектов библиотеки C++ char* для указания на память. Сохранение в памяти как void*, по-видимому, сохранилось по соображениям совместимости как указатель here. Итак, если функция библиотеки cstring не будет использоваться в вашем базовом бит-патерне, используйте поведение конкретных библиотек C++ для ответа на часть вашего вопроса: Предпочитаете char* - void*.

0

Вообще говоря, static_cast будет делать любые два типа, если один из них может быть отлит другим неявно. Это включает в себя арифметические отливки, броски, подбрасывания и отливки до и от void*.

То есть, если этот бросок действительно:

void foo(A a); 
B b; 
foo(b); 

Тогда как static_cast<B>(a) и static_cast<A>(b) также будут действительны.

Поскольку любой указатель может быть введен неявно void*, таким образом, ваше своеобразное поведение.

reinterpret_cast do cast by reinterpreting бит-шаблон значений. Это, как вы сказали в вопросе, обычно делается для преобразования между несвязанными типами указателей.

Да, вы можете конвертировать между несвязанными типами указателей через void*, используя два static_cast:

B *b; 
A *a1 = static_cast<A*>(b); //compiler error 
A *a2 = static_cast<A*>(static_cast<void*>(b)); //it works (evil laugh)! 

Но сгибает правила. Просто используйте reinterpret_cast, если вам это действительно нужно.

 Смежные вопросы

  • Нет связанных вопросов^_^