На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (245) « Первая ... 238 239 [240] 241 242 ...  244 245  ( Перейти к последнему сообщению )  
> Есть ли будущее у DELPHI?
    Цитата Shaggy @
    korvin написал программу, которая не компилируется

    Она компилируется.

    Добавлено
    Опечатки мог бы и сам исправить.

    Однако, я нашел косяк. Теперь все работает, а жаль (для холивара). =) Он был совсем в другом и в примере, который я сюда написал, его нет.
      Мяут-Настоящий, Qraizer
      Не говорите ерунды.
      1) Да, в дельфях тип interface изначально заточен под COM-овский IUnknown и соотв-но должен иметь методы _AddRef и _Release, которые автоматически вызываются компилятором. Но как реализовать эти методы - наше личное дело. И в справке об этом однозначно сказано: если нужна совместимость с COM для связей с "внешним миром" - используй в качестве родителя готовый объект TInterfacedObject, если не нужна - сам задавай методы _AddRef и _Release, как хочешь в соотв-ии со своими "внутренними" задачами. В чем проблема-то? В том, что г-н korvin где-то чё-то услышал об TInterfacedObject и поспешил унаследовать от него подсчет ссылок на интерфейсы с автоудалением объекта, хотя в его задаче "Интерфейсы не надо подсчитывать, они никого не волнуют. Они ничего не хранят, они вообще ничто"?! Дык у него и спросите! (Хотя, если бы он разобрался в принципе подсчета ссылок и работал бы только с интерфейсами, а не с объектами, то тоже все было бы ОК).
      2) Сами подумайте, как может\должен работать подсчет ссылок и нужно ли в конструкторе объекта задавать RefCount != 0. Вызовы _AddRef и _Release подставляются автоматически компилятором в момент присваивания ссылки и ее выхода за пределы области видимости. "По контракту" эти методы существуют и соотв-но вызываются только для наследников интерфейса IUnknown. Обычные объекты не обязаны иметь этих методов, и соотв-но компилятор не обязан для ссылок на обычные объекты проверять их "причастность" к реализации IUnknown и "самовольно" вызывать какие-либо методы. Соотв-но и во время конструирования объекта не известно, будет ли он использоваться как интерфейс или как обычный объект. Поэтому объекты-наследники TInterfacedObject создаются с RefCount=0, а увеличение счетчика происходит только в момент присваиванияя ссылки созданного объекта интерфейсу. Ничего нелогичного, и тем более ужасного, в этом нет. Нужно просто об этом знать и понимать как это работает.

      PS: О любви борманов закладывать в базовые типы TObject, IInterface и т.п, фичи на все случаи жизни, тем самым раздувая их, а с другой стороны ограничивая их использование, уже не раз говорилось и тут, и в дельфийских междусобойчиках. Поэтому повторяться на эту тему не стоит
        leo, проблема в том, что такие интерфейсы - очень странное решение при проектировании языка.
          Цитата leo @
          В чем проблема-то? В том, что г-н korvin где-то чё-то услышал об TInterfacedObject и поспешил унаследовать от него подсчет ссылок на интерфейсы с автоудалением объекта

          И никакой проблемы не было, если бы подсчет ссылок был реализован не через одно место. А заставлять программера разбираться с
          ExpandedWrap disabled
            function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
            function _AddRef: Integer; stdcall;
            function _Release: Integer; stdcall;

          Когда оно нахер не упало --- это да, это по-дельфийски. Прям как с for. Зачем надо было это пихать в базовый интерфейс?

          Цитата leo @
          хотя в его задаче "Интерфейсы не надо подсчитывать, они никого не волнуют. Они ничего не хранят, они вообще ничто"?! Дык у него и спросите! (Хотя, если бы он разобрался в принципе подсчета ссылок и работал бы только с интерфейсами, а не с объектами, то тоже все было бы ОК).

          Расскажи-ка как "работать только с интерфейсами" и где в моем примере "работа с объектами".
            Итак мы выяснили, что в Дельфи "специальные" интерфейсы, и "специальный" цикл for, не похожие на другие языки. ОК.
              Цитата leo @
              где-то чё-то услышал об TInterfacedObject

              Где-то, че-то:
              Цитата
              When defining a class that supports one or more interfaces, it is convenient to use TInterfacedObject as a base class because it implements the methods of IInterface.

              А вот
              Цитата
              if you are using interfaces only internally in your application, then you have a choice that depends upon the nature of your object and how you decide to use it.

              и делфийский подход:
              Цитата
              By implementing these methods yourself, you can provide an alternative means of lifetime management, disabling reference-counting

              --- наделать делов, и заставить программера убирать за авторами.
                leo, ты не о том говоришь. В COM иначе было нельзя, т.к. COM затачивалась как OS-wide фича, которая должна предоставлять необходимый объектный функционал всем приложениям, в частности писаным не только на ООП-языках. С её точки зрения приложение работает с COM-объектами только посредством интерфейсов на них, и ежели объект реализует несколько интерфейсов, о чём приложение знать совершенно не обязано, и даже не обязано, какие объекты реализуют те или иные интерфейсы, они все срыты за UUID, то и подсчитывать нужно интерфейсы. Даже COM-фабрика создаёт объекты по интерфейсам на них. В не объектных языках подсчёт не может выполняться в автоматическом режиме, отсюда и все эти сложности с AddRef и Release.
                В нормальной реалии, когда мы имеем нормально поддержанную объектную парадигму, интерфейс является всего лишь пультом ДУ к объекту. Сам объект создаётся не ссылкой на его интерфейс, а указанием конкретного объекта. Счиатть интерфейсы нафик не надо, считать надо объекты. Нормальные объектные аналоги AddRef и Release прекрасно со всем разберутся безо всякого вмешательства. И создаваемый объект уже имеет счётчик 1, что однозначно отличает его состояние "только что создан" от "последняя ссылка освобождена". Замечу, в реализации COM-сервера эту ситуацию следует обходить явным образом руками.
                  Цитата Qraizer @
                  И создаваемый объект уже имеет счётчик 1, что однозначно отличает его состояние "только что создан" от "последняя ссылка освобождена".

                  какой тяжёлый случай...

                  что хранит счётчик?... количество ссылок
                  кто ссылается на создаваемый объект?... никто
                  чему равен счётчик?... 0
                  ещё вопросы?
                    Цитата Shaggy @
                    Цитата Qraizer @
                    И создаваемый объект уже имеет счётчик 1, что однозначно отличает его состояние "только что создан" от "последняя ссылка освобождена".

                    какой тяжёлый случай...

                    что хранит счётчик?... количество ссылок
                    кто ссылается на создаваемый объект?... никто
                    чему равен счётчик?... 0
                    ещё вопросы?

                    Как это никто не ссылается, если ты обращаешься к нему? 0 возможен только как промежуточное состояние внутри некоторой операции со ссылкой (в процессе создания и возможного удаления удаления объекта). Объект с 0 счётчиком не должен существовать.
                    Сообщение отредактировано: D_KEY -
                      Цитата Shaggy @
                      кто ссылается на создаваемый объект?... никто

                      Т.е. создаваемый объект создается никем и в нигде? Кул стори.
                        Цитата D_KEY @
                        Как это никто не ссылается, если ты обращаешься к нему?

                        где я к нему обращаюсь?

                        вот воплне легальная конструкция

                        TInterfacedObject.Create;

                        где ссылка?
                          Цитата Shaggy @
                          Цитата D_KEY @
                          Как это никто не ссылается, если ты обращаешься к нему?

                          где я к нему обращаюсь?

                          вот воплне легальная конструкция

                          TInterfacedObject.Create;

                          где ссылка?

                          В этой строке и ссылка, ты просто её не назвал. Кстати, тут есть утечка?

                          Добавлено
                          ExpandedWrap disabled
                            make_shared<MyType>();

                          Это тоже легальная конструкция. Тут тоже не должно создаваться счетчиков и должна быть утечка памяти? Нет, спасибо.
                            Цитата D_KEY @
                            Как это никто не ссылается, если ты обращаешься к нему? 0 возможен только как промежуточное состояние внутри некоторой операции со ссылкой (в процессе создания и возможного удаления удаления объекта). Объект с 0 счётчиком не должен существовать.

                            Знаешь как они докатились до жопы такой? Вот смотри:

                            ExpandedWrap disabled
                              procedure Foo(x: IInterface);
                              ...
                              Foo(TInterfacedObject.Create);

                            Объект создается до вызова процедуры, счетчик = 0, передается в процедуру по интерфейсу, счетчик увеличивается до единицы. Процедура завершается, счетчик уменьшается до нуля, объект уничтожается. Все как бы хорошо.

                            Но, как следствие, с полями (и, видимо, с переменными) это не прокатывает.

                            Кстати, что происходит в C++-ных ARC-объектах в таких случаях (создание in-place и тут же передача в процедуру)?
                              Цитата D_KEY @
                              Кстати, тут есть утечка?

                              есть

                              Цитата D_KEY @
                              В этой строке и ссылка, ты просто её не назвал.

                              ручное управление же...
                              конструктор возвращает объектную ссылку(аналог new int, если угодно)
                              их подчсёт не ведётся

                              ExpandedWrap disabled
                                var
                                  O:TObject;
                                begin
                                  O:=TObject.Create;
                                end;

                              тут даже самого счётчика нет

                              ExpandedWrap disabled
                                var
                                  A,B:IInterface;
                                begin
                                  A:=TInterfacedObject.Create;
                                  // A.RefCount = 1
                                  B:=TInterfacedObject.Create as IInterface;
                                  // B.RefCount = 2
                                end;

                              а вот тут есть и то и другое (аналог shared_ptr)
                                Цитата Shaggy @
                                кто ссылается на создаваемый объект?

                                Кстати, D_KEY правильно заметил, если объект существует, но на него никто не ссылается --- это утечка, такие объекты пока только GC умеет удалять.

                                Добавлено
                                Цитата Shaggy @
                                ExpandedWrap disabled
                                  var
                                    A, B: IInterface;
                                  begin
                                    A := TInterfacedObject.Create;
                                    // A.RefCount = 1

                                Замечательно, тогда чем это отличается:
                                ExpandedWrap disabled
                                  TMainForm = ...
                                    FA: IInterface;
                                    ...
                                  end;
                                   
                                  procedure TMainForm.FormCreate;
                                  begin
                                    FA := TInterfacedObject.Create;
                                  end;

                                ?
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (245) « Первая ... 238 239 [240] 241 242 ...  244 245


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,2138 ]   [ 14 queries used ]   [ Generated: 18.07.25, 13:09 GMT ]