
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.62] |
![]() |
|
Страницы: (117) « Первая ... 67 68 [69] 70 71 ... 116 117 ( Перейти к последнему сообщению ) |
Сообщ.
#1021
,
|
|
|
Сообщ.
#1022
,
|
|
|
Из-за оверхедов. Об этом же Архимед стал говорить ![]() Цитата Alex Forth @ Если знаешь ассемблер, то попробуй поработать вместо компилера, посмотрим с каким оверхедом у тебя получится код для работы с интерфейсами. Оверхед минимальный, только счетчик ссылок. Цитата archimed7592 @ ок, приведи мне компилируемый код, следующей структуру(если это вообще возможно): Ну и чего дальше? ![]() ![]() type IMyInterface = interface function Foo(Value: Integer): Boolean; end; TMyImpl1 = class(TInterfacedObject, IMyInterface) function Foo(Value: Integer): Boolean; end; TMyImpl2 = class(TInterfacedObject, IMyInterface) function Foo(Value: Integer): Boolean; end; { TMyImpl1 } function TMyImpl1.Foo(Value: Integer): Boolean; begin Result := Value <> 0; end; { TMyImpl2 } function TMyImpl2.Foo(Value: Integer): Boolean; begin Result := Value = 0; end; procedure InterfaceCall(Intf: IMyInterface); begin ShowMessage(BoolToStr(Intf.Foo(100), True)); end; procedure TForm2.Button1Click(Sender: TObject); var Impl1, Impl2: IMyInterface; begin Impl1 := TMyImpl1.Create; Impl2 := TMyImpl2.Create; InterfaceCall(Impl1); InterfaceCall(Impl2); end; Добавлено Цитата Alex Forth @ Если знаешь ассемблер, то попробуй поработать вместо компилера, посмотрим с каким оверхедом у тебя получится код для работы с интерфейсами. Ну так поделись сведениями. Я же так понимаю ты уже смотрел? ![]() |
Сообщ.
#1023
,
|
|
|
угу, а классы С писать руками? Где ж тут четко распределено? Нужно решать от какого наследоваться, какие писать руками, какие в интерфейсы заворачивать и все это лдя того чтобы смоделировать множественное наследование? оО это считается удобно? ![]() Цитата Smike @ Зато я могу например вместо одной подсунуть любую другую. А как это с множественным наследованием? А главное, классы-имплементоры совершенно не зависят от класса-агрегатора. юзать шаблоны? вот тут непонял. Есть несколько обектов - нужно "собрать" один. Делаешь множественное наследование - и опа собран. Тебе же для каждого случая нужно писать отдельную реализацию с интерфейсом |
![]() |
Сообщ.
#1024
,
|
|
Цитата Smike @ Ну и чего дальше? Зачем нужно было придираться к моему коду, если ты написал то же самое, только описал сами интерфейсы и классы? 0_о Дальше расскажи мне, как работает ф-ция interfaceCall... Откуда она знает какую ф-цию вызывать(вспоминаем, что для того чтобы вызвать ф-цию нужно знать её адрес)? Скажем, если экспортировать эту ф-цию в dll'ку, то компилятор даже если очень захочет, не сможет нашлёпать все возможные вариации ф-ции interfaceCall(да он, и так этого делать не станет - он просто поставит тебя перед фактом полиморфного оверхэда). |
Сообщ.
#1025
,
|
|
|
Цитата Орион @ угу, а классы С писать руками? Где ж тут четко распределено? Нужно решать от какого наследоваться, какие писать руками, какие в интерфейсы заворачивать и все это лдя того чтобы смоделировать множественное наследование? оО это считается удобно? ![]() А ты абстрагируйся от того что ты привык делать в плюсах и посмотри на это с точки зрения логики. У тебя есть реализация ходов ладьи и слона, тебе нужно сделать хода ферзя. Ты всего навсего объединяешь реализации обоих типов ходов в одном классе. Причем можно писать различные независимые реализации и менять их в зависимости от какого-то параметра. Вот кстати, приведи-ка мне полный аналог моего примера, используя только множественное наследование ![]() Добавлено Цитата archimed7592 @ Зачем нужно было придираться к моему коду, если ты написал то же самое, только описал сами интерфейсы и классы? 0_о Ты написал неправильно, твой код не скомпилится. Цитата archimed7592 @ Откуда она знает какую ф-цию вызывать(вспоминаем, что для того чтобы вызвать ф-цию нужно знать её адрес)? Если предположить, что интерфейс является неким контейнером смещений функций конкретного класса, то эта функция получает уже готовый интерфейс и сможет определить, по какому адресу находится нужная функция. Цитата archimed7592 @ Скажем, если экспортировать эту ф-цию в dll'ку, то компилятор даже если очень захочет, не сможет нашлёпать все возможные вариации ф-ции interfaceCall(да он, и так этого делать не станет - он просто поставит тебя перед фактом полиморфного оверхэда). В Delphi сможет (так как используется единая реализация интерфейсов). |
Сообщ.
#1026
,
|
|
|
Цитата Smike @ Из-за оверхедов. Об этом же Архимед стал говорить ![]() каких? в С++ абстрактные классы не тянут за собой Win32 мишуру, как это в Delphi... Добавлено Цитата Smike @ Цитата (archimed7592 @ Сегодня, 15:25) Смайки, ты что, действительно думаешь, что интерфейс - это конструкция, не использующая полиморфизма(виртуальные ф-ции и иже с ними)? ![]() В Delphi — да ![]() Цитата Smike @ Если предположить, что интерфейс является неким контейнером смещений функций конкретного класса, то эта функция получает уже готовый интерфейс и сможет определить, по какому адресу находится нужная функция. Вот ты и аргументировал. Полностью подтвердив слова Архимеда. ![]() |
![]() |
Сообщ.
#1027
,
|
|
Цитата Smike @ Если предположить, что интерфейс является неким контейнером смещений функций конкретного класса, то эта функция получает уже готовый интерфейс и сможет определить, по какому адресу находится нужная функция. Ну, во-первых, либо ты знаешь как реализованы интерфейсы в Delphi, либо ты только предполагаешь. Во-вторых: таблица смещений - это по твоему не полиморфизм? 0_о Добавлено Цитата Smike @ В Delphi сможет (так как используется единая реализация интерфейсов). Ты просто не понял что я имел ввиду, ну да ладно... Раз уж мы определились с таблицей смещений, то проехали ![]() |
Сообщ.
#1028
,
|
|
|
Цитата daevaorn @ каких? в С++ абстрактные классы не тянут за собой Win32 мишуру, как это в Delphi... Мсье окончательно утратил какую-либо убедительность в моих глазах. Цитата archimed7592 @ Ну, во-первых, либо ты знаешь как реализованы интерфейсы в Delphi, либо ты только предполагаешь. Во-вторых: таблица смещений - это по твоему не полиморфизм? 0_о Ну во-первых здесь появились гуру DCC32, которые решили меня переубедить. Даю им фору ![]() Во-вторых, полиморфизм предполагает наличие таблицы виртуальных методов, а не смещений функций в конкретном классе. |
Сообщ.
#1029
,
|
|
|
Цитата Smike @ Во-вторых, полиморфизм предполагает наличие таблицы виртуальных методов, а не смещений функций в конкретном классе. я плакал ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Цитата Smike @ Мсье окончательно утратил какую-либо убедительность в моих глазах. я хоть не позорюсь незнанием инструмента, за который ратую, как некоторые ![]() |
Сообщ.
#1030
,
|
|
|
![]() ![]() Unit2.pas.55: Intf.Foo(100); 004564D1 BA64000000 mov edx,$00000064 004564D6 8B45FC mov eax,[ebp-$04] 004564D9 8B08 mov ecx,[eax] 004564DB FF510C call dword ptr [ecx+$0c] Вычисляется адрес конкретной процедуры по фиксированному смещению. |
Сообщ.
#1031
,
|
|
|
Цитата Smike @ Во-вторых, полиморфизм предполагает наличие таблицы виртуальных методов, а не смещений функций в конкретном классе. полиморфизм не предполагает ни того ни другого. Он лиш предполагает что вызов таких функций будет работать (и будут вызыватся функции из базового класса). Таблица смещений? Это что вообще? Что за смещение функции? Смещение относительно чего? в чем разница - пощитать адрес прибавив смещение к чемуто, от пощитать адрес взяв ее из таблицы? И вообще... оверхед вызова виртуальной функции это что? ![]() |
Сообщ.
#1032
,
|
|
|
Цитата Smike @ Вычисляется адрес конкретной процедуры по фиксированному смещению. а посмотри теперь виртуальный метод. |
![]() |
Сообщ.
#1033
,
|
|
Цитата daevaorn @ я плакал ![]() Аналогично ![]() Цитата Smike @ Мсье окончательно утратил какую-либо убедительность в моих глазах. Мишура - это GUID и reference counting сделаный по образу и подобию COM. Цитата Smike @ Ну во-первых здесь появились гуру DCC32, которые решили меня переубедить. Даю им фору ![]() Я лишь знаю как реализуется полиморфизм в компиляторах в общем а не кокнкретно в твоём DCC32... Ты видимо вообще не понимаешь как работает полиморфизм. Цитата Smike @ Во-вторых, полиморфизм предполагает наличие таблицы виртуальных методов, а не смещений функций в конкретном классе. Ну хорошо, подводим итог: C++ в compile-time выбросит вызов ф-ции вообще, в Delphi же будет вычислена таблица смещений, потом передана куда-то, потом из неё будет вытянут адрес по конкретному смещению и, наконец сделан вызов dummy ф-ции. Оверхэд очевиден? |
Сообщ.
#1034
,
|
|
|
Как раз наоборот. Всего-то 63 стандартных (плюс ещё для сокращённого набора символов всякие and, or, not, ... ) - в этом смысле C++ гораздо проще, проще него только C. |
Сообщ.
#1035
,
|
|
|
Цитата Smike @ Вычисляется адрес конкретной процедуры по фиксированному смещению. не.. это и есть таблица.. то что ты привел.. вот С++ вариант ![]() ![]() class I { public: virtual void foo (int) = 0; }; class II : public I { public: void foo (int) { } }; int main () { I* i = new II; i->foo (100); 00446766 push 64h 00446768 mov eax,dword ptr [i] 0044676B mov edx,dword ptr [eax] 0044676D mov ecx,dword ptr [i] 00446770 mov eax,dword ptr [edx] 00446772 call eax } тут больше так как еще работа с i идет. В делфи навернякак такойже обсолютно указатель на таблицу виртуальных функций, иначе неработал бы в делфи COM. Или он там не работает?? я просто не знаю... |