Зачем мне использовать dynamic_cast для приведения в void *? - PullRequest
12 голосов
/ 28 февраля 2012

Итак, я читал ответы на dynamic_cast из "void *" , и хотя вы не можете разыграть от void * до T *, некоторые из ответов указывают на то, что возможно приведите T * к void *, но не указывайте , почему вы хотите сделать это.

Это просто мелочи, которые возможны, или есть случай, когда это имело бы смысл? Я подумал, может быть, для удобства чтения или чтобы было ясно, что мы конвертируем в void *, но, учитывая цель dynamic_cast, он мне не очень подходит.

В этом отношении, есть ли причина делать что-то кроме того, чтобы T * стал void * неявно? Я видел приведение в стиле C к void *, которое время от времени использовалось для этой цели, я предполагаю, что это просто явно (при условии, что мы не делаем ничего необычного, например приведение int к указателю или что-то в этом роде).

Ответы [ 2 ]

10 голосов
/ 28 февраля 2012

Во-первых, при использовании dynamic_cast<void*>(x) вы получаете указатель на первый байт самого производного объекта. Пока статический тип x является полиморфным.

Это может быть полезно в нескольких сценариях, где адрес служит идентификатором объекта:

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

Конечно, это, конечно, не ежедневное использование , но в C ++ адрес памяти является де-факто идентификатором для объектов, поэтому механизм доступа к нему из любой части иерархии наследования, безусловно, полезен для тех немногих крайних случаев.

5 голосов
/ 28 февраля 2012

У этого есть цель, вроде. На это намекает та часть спецификации, которая это позволяет. От N3337, раздел 5.2.7, пункт 7:

Если T - «указатель на cv void», то результатом является указатель на наиболее производный объект, на который указывает v.

Так что dynamic_cast<void*>(...) - это сокращение от static_cast<void*>(dynamic_cast<MostDerivedType*>(...)). И это было бы полезно ... вроде.

Сложность в том, чтобы сделать его полезным, заключается в том, что вы не обязательно знаете, что такое MostDerivedType. Ведь оно может быть разным для каждого выражения. Поэтому, если у вас есть void*, у вас не обязательно есть способ вернуть его обратно безопасно . Если вы сделаете предположение о MostDerivedType и просто static_cast, и вы ошиблись , то вы окажетесь в неопределенной стране поведения. Принимая во внимание, что если вы сделаете dynamic_cast для этого типа (затем от static_cast до void*), оно, по крайней мере, вернет NULL, если это не тот тип.

Так что нет, я бы сказал, что это не очень полезно. Нет, если вы хотите жить в границах C ++ и не полагаться на потенциально неопределенное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...