Как работают динамические приведения?

Допустим, у меня есть тип A и производный тип B. Когда я выполняю динамическое приведение от A * к B *, какие «проверки во время выполнения» выполняет среда? Откуда он знает, что актеры законны?
Я предполагаю, что в .Net можно использовать прикрепленные метаданные в заголовке объекта, но что происходит в C ++?

7.11.2009 13:56:02
4 ОТВЕТА
РЕШЕНИЕ

Точный алгоритм зависит от компилятора. Вот как это работает в соответствии со стандартом Itanium C ++ ABI (2.9.7) (написано после и после GCC).

Указатель на базовый класс - это указатель на середину тела «большого» класса. Тело «большого» класса собрано таким образом, что независимо от того, на какой базовый класс указывает указатель, вы можете получить единый доступ к RTTI для того «большого» класса, которым на самом деле является ваш «базовый» класс . Этот RTTI представляет собой особую структуру, которая относится к информации «большого» класса: какого она типа, на каких основаниях и с какими смещениями.

По сути, это «метаданные» класса, но в более «двоичном» стиле.

V instance;
Base *v = &instance;
dynamic_cast<T>(v);

Динамическое приведение использует тот факт, что когда вы пишете dynamic_cast<T>(v), компилятор может немедленно идентифицировать метаданные для «большого» класса v - то есть V! Когда вы пишете его, вы думаете, что Tон более производный Base, так что компилятору будет трудно выполнить приведение от базы к приводу. Но компилятор может немедленно (во время выполнения) определить наиболее удаленный тип V- и ему нужно только затем пройти по графу наследования, содержащемуся в метаданных, чтобы проверить, может ли он быть понижен Vдо T. Если это возможно, он просто проверяет смещение. Если это невозможно или неоднозначно - возвращается NULL.

3
7.11.2009 14:54:15

Динамическое приведение выполняет проверку во время выполнения, является ли это допустимым и выполнимым приведением; он вернет NULL, когда невозможно выполнить приведение.

0
7.11.2009 14:01:48
Или, если по ссылочному типу он выдаст std :: bad_cast
Ben 7.11.2009 14:04:02

Динамическое приведение - двухэтапный процесс:

  1. Учитывая vtable указателя на объект, используйте смещение, чтобы восстановить указатель на полный класс. (Все корректировки будут сделаны из этого указателя.) Это эквивалентно понижению до полного класса.

  2. Найдите в type_info полного класса нужный нам тип - другими словами, просмотрите список всех баз. Если мы найдем его, используйте смещение, чтобы снова настроить указатель. Если поиск на шаге 2 не удался, верните NULL.

3
7.11.2009 14:05:28

Ссылайтесь на свою любимую книгу по RTTI.

-2
7.11.2009 14:05:59