Карманный справочник O'Reilly по Objective-C утверждает, что C++ не поддерживает Dynamic Dispatch, правда ли это?

На странице 4 написано:

Objective-C решает динамически — во время выполнения — какой код будет обрабатывать сообщение путем поиска класса получателя и родительских классов. (Среда выполнения Objective-C кэширует результаты поиска для повышения производительности.) Компилятор C++, напротив, строит таблицу диспетчеризации статически — во время компиляции.

Я много читал в StackOverflow и Википедии, и достаточно сказать, что я совершенно не понимаю, поддерживает ли C++ Dynamic Dispatch (который, по мнению некоторых, является реализацией Dynamic Binding).

Кто-нибудь может прояснить разницу между динамической отправкой, динамической привязкой и тем, поддерживает ли С++ один из них или оба? Я не эксперт по C++ или Objective-C, я пришел из мира Java, Python и PHP.


person stantonk    schedule 02.01.2012    source источник
comment
Я не думаю, что в этой книге говорится, что C++ не поддерживает динамическую диспетчеризацию. Я думаю, это говорит о том, что в С++ таблица отправки (используемая для динамической отправки) создается во время компиляции (т.е. статически). Это верно, по крайней мере, для многих распространенных реализаций C++. Однако я ничего не знаю о Objective-C, поэтому я не могу сравнить это с тем, что делает Objective-C.   -  person James McNellis    schedule 03.01.2012
comment
Я думаю, это зависит от того, как вы их определяете. Я думаю, что большинство людей сказали бы, что C++ имеет динамическую диспетчеризацию, хотя большинству реализаций не нужно выполнять поиск во время выполнения для достижения этого.   -  person Oliver Charlesworth    schedule 03.01.2012
comment
Я добавил тег objective-c. Обсуждение, вероятно, было бы полезно для людей, разбирающихся в objective-c   -  person David Rodríguez - dribeas    schedule 03.01.2012


Ответы (6)


Динамическая диспетчеризация, упоминаемая в этой книге, вероятно, является другой динамической диспетчеризацией, обычно упоминаемой в контексте C++:

  • C++ поддерживает динамическую диспетчеризацию в виде виртуальных функций. Соответствующие имена и параметры действительно известны во время компиляции, хотя фактическая вызываемая функция зависит от динамического типа объекта.
  • Я не эксперт по Objective C, но я понимаю, что вы можете динамически добавлять функции к отдельным объектам во время выполнения, которые просматриваются при вызове. C++ не поддерживает такого рода динамическую диспетчеризацию.
person Dietmar Kühl    schedule 02.01.2012

C++ поддерживает динамическую диспетчеризацию через виртуальные функции-члены.

Я не думаю, что эта книга говорит об обратном. В нем говорится, что «компилятор C++ строит таблицу диспетчеризации статически — во время компиляции». Это правда: таблицы диспетчеризации ("vtable"), которые используются для реализации динамической диспетчеризации, создаются во время компиляции, по крайней мере, в наиболее распространенных реализациях C++.

person James McNellis    schedule 02.01.2012

Ваш заголовок отличается от вашего вопроса.

Утверждение из книги верно: виртуальная диспетчеризация С++ выполняется во время выполнения, но таблицы диспетчеризации генерируются во время компиляции. Однако это не то же самое, что сказать, что С++ не поддерживает "динамическую диспетчеризацию". Виртуальные функции — это форма динамической отправки, но есть много уровней вещей, которые регистрируются под термином "динамическая отправка".

person Nicol Bolas    schedule 02.01.2012
comment
Кажется, в книге четко указано, что C++ не поддерживает динамическую отправку, которая, по-видимому, определяется в книге как способная определить во время выполнения, какой метод отправить в ответ на сообщение, путем поиска получателя и это родительские классы. Я думаю, что путаница, возможно, заключается в том, что в Objective-C класс получателя сообщения может не иметь метода для отправки в ответ в какой-то момент во время рабочего жизненного цикла приложения, но позже в том же запуске приложения к этому целевому классу мог быть добавлен новый метод, позволяющий ему отвечать. - person stantonk; 04.01.2012
comment
Проблема, кажется, в том, что использование самого термина «Динамический» перегружается :-P. Поскольку C++ создает таблицы диспетчеризации статически, то как он может поддерживать динамическую диспетчеризацию... таблицы диспетчеризации являются статическими. Objective-C позволяет изменять таблицы диспетчеризации во время выполнения. Я что-то упускаю? - person stantonk; 04.01.2012
comment
Если вы не говорите о части книги, которую вы не цитировали, сама книга никогда не использует термин динамическая отправка. Он очень четко объясняет поведение ObjectiveC и C++, но никогда не использует термин, о котором вы спрашивали. - person Nicol Bolas; 04.01.2012
comment
Что касается того, как С++ может иметь динамическую диспетчеризацию, все зависит от того, как вы определяете этот термин. Поскольку ни вы, ни книга не определили его, его можно определить, используя любое из различных определений. C++ позволяет посредством полиморфизма использовать производные классы в качестве базовых классов. Поскольку фрагмент кода не может статически знать, какой метод вызовет вызов виртуальной функции (он может вызвать реализацию базового класса или любую реализацию производного класса), он является динамическим. вызов. Следовательно: динамическая отправка. - person Nicol Bolas; 04.01.2012

Если «динамическая диспетчеризация» означает «изменить во время выполнения, какая функция вызывается для вызова метода для данного объекта», тогда да: C++ не имеет - на уровне языка - структурированного собственного механизма для этого (это означает изменить во время выполнения указатель v-таблицы или даже указатель функции внутри v-таблицы: это возможно путем принудительной реализации конкретных конструкций, но может навредить детям :-) относитесь к этому как к "порнокодированию"!)

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

person Emilio Garavaglia    schedule 02.01.2012

По сути, С++ является «частично» динамическим, используя ключевое слово «виртуальный». мы обычно называем эту функцию «поздней привязкой метода», которая определяет конкретный метод для вызова во время выполнения.

OC, однако, является «чистой» динамической (не такой чистой, как javascript) благодаря своей мощной системе выполнения. вы можете добавлять методы и переменные во время выполнения, не говоря уже о выборе правильного метода для вызова во время выполнения. мы обычно называем эту функцию «динамической отправкой сообщений».

Как видите, с точки зрения вызова метода они работают почти одинаково. подробный процесс поиска метода отличается (c++ просматривает виртуальную таблицу, может попытать счастья в списке методов своего класса), но они оба получают свою гибкость во время выполнения.

person peak    schedule 07.01.2014

C++ поддерживает динамическую отправку через виртуальные функции .

Однако он (изначально) не поддерживает двойную отправку, которая система, которая определяет вызываемый метод на основе типа среды выполнения объекта и типа среды выполнения параметров метода.

person aeskr    schedule 02.01.2012