Где выполняется переопределение функции? - PullRequest
5 голосов
/ 25 июля 2011

Где в процессе создания программы, компилятора, компоновщика и т. Д. Выполняется переопределение функций и перегрузка операторов?

Мне особенно интересно, где это делается в C ++, Ruby и Python.

Ответы [ 3 ]

4 голосов
/ 25 июля 2011

Функция перегрузка (по крайней мере, в C ++) обрабатывается внутри компилятора. Идея состоит в том, что код, который в конечном итоге генерирует компилятор, будет жестко задан для вызова соответствующей функции, как если бы все функции имели разные имена, и вы вызвали функцию, уникально подходящую для аргументов. В более общем случае, в большинстве компилируемых языках, которые поддерживают перегрузку, разрешение перегрузки выполняется во время компиляции, и выданный код всегда будет вызывать указанную функцию. Например, Haskell поддерживает перегрузку во время компиляции таким образом.

Перегрузка оператора является частным случаем общей перегрузки, поэтому обычно она обрабатывается одинаково.

Функция переопределение (термин, который возникает в ООП, когда производный класс наследует от базового класса и переопределяет один из его методов), почти всегда разрешается во время выполнения, поскольку компилятор не всегда может сказать, какой Функция будет вызываться без фактического знания типов во время выполнения. Некоторые компиляторы могут быть в состоянии статически доказать, что определенный объект имеет определенный тип, а затем оптимизировать динамическую отправку, но это невозможно сделать во всех случаях.

Мне неизвестны какие-либо динамические языки, поддерживающие перегрузку, поскольку теоретически вы могли бы вводить новых кандидатов на перегрузку во время работы программы. Я хотел бы быть просветленным, если такой язык существует.

3 голосов
/ 25 июля 2011

Для C ++ перегрузка операторов выполняется на уровне компилятора, хотя процесс обработки имен, который создает уникальный идентификатор имени для каждой функции, чтобы компоновщик не жаловался на дублирующиеся определения функций. В C ++ возможна перегрузка операторов, потому что перегружаемые операции, такие как +, -, * и т. Д., Сами являются собственными функциями, которые имеют префикс operator, за которым следует символ операции. Так, например, перегруженная функция operator+ с сигнатурой функции, такой как

my_type operator+(const my_type& lhs, const my_type& rhs);

не будет конфликтовать с другой функцией operator+ с другой сигнатурой, даже если обе функции имеют одинаковое имя operator+, потому что каждая версия функции будет иметь другое имя на уровне языка ассемблера после компилятора C ++. процесс искажения имени завершен. Упорядочивание имен имеет еще одно преимущество, заключающееся в том, что скомпилированный код C и C ++ может использоваться с одним и тем же компоновщиком, поскольку две функции с одним и тем же именем не будут существовать и будут вызывать ошибку компоновщика.

Обратите внимание, что в C, даже если вы создаете две функции с разными сигнатурами, если они имеют одно и то же имя, поскольку компилятор C не будет выполнять какие-либо манипуляции с именами, компоновщик будет жаловаться на дублирующиеся определения функции.

0 голосов
/ 25 июля 2011

Python не связан / не скомпилирован, он интерпретируется.Таким образом, обычное переопределение выполняется при разборе источников классов.Конечно, из-за динамического характера вы всегда можете переопределить и во время выполнения.Я предполагаю, что альтернативные реализации, использующие компиляцию байтового кода, делают это во время компиляции.

Я также думаю, что вышеупомянутое верно и для Ruby.

...