c
и &d
действительно имеют одно и то же значение, и если вы переинтерпретируете приведение c
обратно к D*
, вы получите действительный указатель, который вы можете разыменовать. Кроме того, вы можете рассматривать c
как (указатель на первый элемент) непрозрачного массива char[sizeof(D)]
- это действительно основная цель приведения указателей к указателям на символы: разрешить (де) сериализацию (например, ofile.write(c, sizeof(D));
) , хотя обычно это следует делать только для примитивных типов (и их массивов), поскольку двоичная компоновка составных типов обычно не указывается переносимым образом.
Как правильно заметил @Oli и хотел бы, чтобы я подтвердил, вам никогда не следует сериализовать составные типы в целом. Результат почти никогда не будет десериализуемым, поскольку реализация полиморфных классов и заполнения между полями данных не указана и недоступна для вас.
Обратите внимание, что reinterpret_cast<char*>(static_cast<B*>(&d))
может рассматриваться как непрозрачный массив char[sizeof(B)]
по аналогичным рассуждениям.