2017-02-22 10 views
2

В чем смысл приведения указателя в C++?Каково значение указателя на cast (const char *) в C++?

Например, что делает запись?

Зачем он ссылается на uint32_t указатель на (const char *) ??

class A{ 
     uint32_t a;// initialized by some value 
     void write(ostream& os){ 
        os.write((const char*)&a, sizeof(a)); 
     } 
}; 
+0

Кастинг 'uint32_t' на' char' через указатель, вероятно, вызовет разное поведение на маленьких конечных и больших энтианских машинах. – JHBonarius

ответ

2

Это может помочь, если вы посмотрите на documentation of ostream::write:

basic_ostream& write(const char_type* s, std::streamsize count); 

Ведет себя как UnformattedOutputFunction. [...]

Так write выполняет неформатированную запись на поток. Это означает отсутствие форматирования текста, преобразования и т. Д. (Например, новые строки). Для этого он требует наличия буфера байтов для вставки в поток. К сожалению, C++ не имеет типа byte как гражданин первого класса. Вместо этого используется char. Вот почему бросок на const char*.

0

Это сериализация некоторой структуры данных.

В чем смысл приведения указателя в C++?

ofstream::write ожидает const char* s в качестве первого параметра

Почему это бросало uint32_t указатель (сопзЬ сЬаг *) ??

он записывает четыре байта в некоторый поток (целое число без знака), возможно, в std :: ofstream. Таким образом, он записывает значение, хранящееся в a, например, в файл.

0

Функция член write объявлена ​​следующим образом

basic_ostream<charT,traits>& write(const char_type* s, streamsize n); 

Как вы видите его первый параметр имеет тип const char_type *

В этом вызове

os.write((const char*)&a, sizeof(a) 

там используется указатель типа uint32_t *. Однако неявное преобразование из типа uint32_t * в тип const char_type * в C++. Таким образом, используется явное преобразование, то есть попытка записать объект типа uint32_t в виде последовательности байтов.

2

Указатели - это переменные, в которых хранятся ячейки памяти. Таким образом, все указатели имеют один и тот же диапазон значений (целые числа от 0 до максимального места памяти поддержки).

Теперь указатели поддерживают операцию, называемую разыменованием: доступ к объекту, хранящемуся на этом адресе памяти. Если у вас есть адрес памяти, и вы хотите получить доступ к этому объекту, вам нужно знать вещи как размер объекта (в байтах) и много вещей, связанных с тем, как фактически интерпретировать значения там. Все это известно по типу.Итак, у нас есть указатели разных типов, и мы можем конвертировать между ними, поскольку все они имеют одну и ту же область значений.

Это означает, что, изменяя тип указателя, вы можете иметь другую интерпретацию одного и того же объекта.

Вернемся к вашему вопросу. Функция записи, которую вы указали, должна записываться в байтовый поток по байтам (имеет отношение ко многим причинам, например, тот факт, что байт является наименьшей единицей хранения, поэтому вы можете писать что угодно, записывая свои байты). Теперь у вас есть 4 байта int, к которому вы хотите получить байтовый байт. Как вы это делаете? Просто получив указатель на него, преобразуйте его в тип размера байта (char) и получите доступ к 4 байтам, используя арифметику указателя (в основном доступ к 4 последовательным ячейкам памяти) - вот почему вам также нужно отправить размер типа. В качестве меры предосторожности запрашиваемый тип первого аргумента - const char*, чтобы гарантировать, что он не изменит данные.

Теперь, в вашем случае, литье (преобразование указателя) было сделано явным.

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