2009-11-07 5 views
4

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

ответ

3

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

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

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

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

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

0

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

+2

Или, если на ссылочном типе будет выбрано std :: bad_cast – Ben

3

Dynamic литого процесс состоит из двух этапов:

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

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

-2

Отремонтируйте свою любимую книгу на RTTI.

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