Я читал StackOverflow слишком много и начал сомневаться относительно всего кода, который я когда-либо писал, я продолжаю думать, "То, что неопределенный behavour?" даже в коде, который работал целую вечность.
Таким образом, мой вопрос - Является этим безопасный и четко определенный behavour, чтобы бросить указатель на объект (В этом интерфейсе краткого обзора случая классы) к пустоте* и затем позже бросить их назад к исходному классу и методу вызова с помощью них?
Я полностью осведомлен, что код, который делает это, вероятно, ужасен. Я даже не рассмотрел бы запись его как это теперь (это - старый код, который я действительно не хочу изменять), таким образом, я не ищу обсуждение лучших способов сделать это. Я уже знаю, как записать это лучше, если я когда-нибудь делал это снова. Но если это на самом деле повреждается для доверия этому в C++ затем, я должен буду посмотреть на изменение кода, если это будет просто ужасный код, затем изменяющий его, то не будет приоритет.
У меня не было бы сомнений относительно чего-то это простое год или два назад, но как мое понимание увеличений C++, я на самом деле нахожу, что у меня есть все больше беспокойства о коде, являющемся безопасным в соответствии со стандартами, даже если это работает отлично. Возможно, чтение слишком большого переполнения стека является плохой вещью для производительности иногда :P
Вы в безопасности.
Из проекта C ++ (0x),
§5.2.9 / 13 (для static_cast
):
Значение указателя типа на объект преобразовано в «указатель на cv
void
”и обратно, возможно, с другим cv-квалификацией, должны иметь свое исходное значение.
§5.2.10 / 7 (для reinterpret_cast
):
Преобразование rvalue типа «указатель на
T1
» в тип «указатель наT2
»(гдеT1
иT2
- это типы объектов, а требования к выравниваниюT2
не строже, чем требованияT1
)) и возврат к исходному типу дает исходное значение указателя.
(Конечно, приведение к несвязанному классу является неопределенным поведением.)
Итак, мой вопрос - является ли безопасным и хорошо определенным поведением приведение указателя на объект (в данном случае абстрактные интерфейсные классы) к void*, а затем последующее приведение их обратно к исходному классу и вызов метода, использующего их?
Да - при условии, что вы приводите указатель обратно к точно такому же типу. В противном случае корректировка указателя базового класса может уничтожить значение указателя.
На практике это (вероятно) актуально только при использовании множественного наследования: указатели на производный класс могут отличаться по физическому адресу от указателей на базовый класс.