
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.30] |
![]() |
|
Страницы: (245) « Первая ... 241 242 [243] 244 245 ( Перейти к последнему сообщению ) |
![]() |
Сообщ.
#3631
,
|
|
Я не думаю, что от него хоть какой-то прок будет, пусть даже маленький. Однако библиотеки есть, хоть и маловостребованы. Значит, кому-то нужно, а я просто не в курсе.
|
Сообщ.
#3632
,
|
|
|
![]() ![]() |
![]() |
Сообщ.
#3633
,
|
|
О, блин. Долго ждал
![]() |
![]() |
Сообщ.
#3634
,
|
|
ничего не понял. что за иерархия? если ту имеешь в виду то, что нужно наследоваться от TInterfacedObject то это не так декларируется ручное управление временем жизни, конструктор возвращает соответствующую ссылку поведение соответствует декларируемому. что-то не так? автоматическое управление и подсчёт ссылок обеспечивается другим механизмом - интерфейсами и тут приходит Qraizer и говорит, что для реализации этого нам нужно автоматическое управление во первых, нахрена, если и так работает, работает правильно, как и задумывалось? во вторых, только я тут вижу бесконечную рекурсию? Цитата Qraizer @ Никто не владеет, некому и считать ссылки. Отсюда в частности и обсуждаемые проблемы.Не надо считать? Ну ладно, а зачем тогда было вводить счётчики? Ах, всё-таки надо... тогда почему такую простейшую задачу надо выполнять руками? На кой хрен сдался этот интерфейс, который не умеет того, для чего создавался - избавить программера от рутины? raw mind? выдуманные проблемы с++шников, которые лезут со своим уставом в чужой монастырь не переопределять, а писать с нуля, этих методов нет в TObject если мы хотим автоматики стандартный шаблон: 1. создаём объект 2. запрашиваем интерфейс(любой из тех, что реализованы) 3. и далее работаем с объектом только посредством интерфейсов 4. если нам надо передать интерфейс в функцию/метод без увеличения счётчика, используем const(пример я уже приводил) ![]() ![]() var O:TObj; I:IMyIntf; begin O:=TObj.Create; I:=O as IMyIntf; I.Work; doSomething(I); end; на практике, объектная ссылка просто не нужна ![]() ![]() var I:IMyIntf; begin I:=TObj.Create; I.Work; doSomething(I); end; иногда возникает ситуация, когда в программе мы работаем только с объектами, а в какую-то внешнюю функцию надо передать интерфейс(т.е. писали её не мы и изменить не можем) тут два варианта а) либо в соответствии с п.3 переписываем всё на интерфейсах б) либо реализуем интерфейс только там, где нужно, без подсчёта ссылок (видимо сценарий действительно редкий и стандартной заготовки нет. пришлось изобретать TNoRefObject) (тут использование const на счётчик не повлияет т.к. его нет ![]() насколько знаю С++ - тоже из shared_ptr можно получить сырой указатель? Цитата korvin @ Что "и?" Либо считайте ссылки объекта, либо не уничтожайте объект при значении счетчика == 0. Отсутствие интерфейсных ссылок на объект не означает отсутствия "классовых" ссылок на объект. ссылка на объект(весь интерфейс объекта) vs часть этого интерфейса. и какая разница? Цитата korvin @ Либо считайте ссылки объекта, либо не уничтожайте объект при значении счетчика == 0. считаем, не уничтожается уничтожается при переходе 1->0 хинтов по поводу? все контракты выполняются никаких неоднозначностей нет все переменные инициализированы просто ты захотел выстрелить себе в ногу у тебя получилось... кстати тут счётчик равен чему? судя по объяснениям Qraizer - 2 ? |
Сообщ.
#3635
,
|
|
|
Цитата Shaggy @ тут счётчик равен чему? судя по объяснениям Qraizer - 2 По его объяснениям (и по факту) счётчик здесь равен 1. Как и в Objective-C. Только в дельфях всё через... |
![]() |
Сообщ.
#3636
,
|
|
Цитата Shaggy @ Ух ты ж. На предмет порога вхождения в Дельфи ответ будет? У korvin-а пока получается лихо пороги переступать везде, кроме Дельфей. В Плюсы в частности. Количество переступленных порогов можно у него уточнить. И вот после ответов мы наконец-то сможем внятно поговорить о месторасположении рога изобилия проблем.выдуманные проблемы с++шников, которые лезут со своим уставом в чужой монастырь Цитата MyNameIsIgor @ MyNameIsIgor, если б он читал, что ему пишут, а не искал знакомые буквы, то вот это вотя б не спрашивал.о его объяснениям (и по факту) счётчик здесь равен 1. Как и в Objective-C. Только в дельфях всё через... И -- да, в Дельфях если не вообще всё, то уж точно всё растущее из Абракадеро, через. Ибо и вот это вотсказанное в адрес Objective-C, не насторожило. Shaggy, вас Абракадеро очередной раз кинуло, поленившись сделать правильно и сделав, как им проще, вам втюхать как догму, а вы и рады уши развесить. Кроме Дельфей, нигде больше ссылки так не считают. Всё, что есть Дельфях, можно найти ещё где-нибудь. Любые качества, фичи, итд. Но вот ссылки на интерфейсы есть только тут. Ну ещё в COM, но это и не язык. |
![]() |
Сообщ.
#3637
,
|
|
Цитата Shaggy @ (видимо сценарий действительно редкий и стандартной заготовки нет. пришлось изобретать TNoRefObject) Потому и редкий, что "всё через..." Цитата Shaggy @ из shared_ptr можно получить сырой указатель? Угу, только shared_ptr -- 1) это другой объект, а не наш, 2) использование shared_ptr не ограничивает меня в способах построения иерархии своих классов. Цитата Shaggy @ ссылка на объект(весь интерфейс объекта) vs часть этого интерфейса. и какая разница? Так это у вас надо спрашивать, у вас же разница есть. Цитата Shaggy @ уничтожается при переходе 1->0 Об этом и речь. Цитата Shaggy @ просто ты захотел выстрелить себе в ногу у тебя получилось... Просто, как обычно, у Делфи свой путь. Куда-то далеко. Добавлено Цитата Qraizer @ растущее из Абракадеро Так это наверное еще со времен Борланда тянется. Добавлено BTW, почему было изначально не сделать управление жизнью объектов только через ARC, не было бы путаницы и это снизило бы порог вхождения. У меня два живых примера "перед глазами", оба пишут на Делфи, но оба понятия не имеют про классы/объекты/динамическую память/время жизни. Потому и пишут фактически процедурный код. Слишком сложно в объекты для формошлеперов. Добавлено Цитата Shaggy @ тут два варианта Я так понимаю, решение проблемы циклических ссылок тоже отдан на откуп программисту: ![]() ![]() program Test; {$APPTYPE CONSOLE} {$R *.res} uses SysUtils, Classes; type ICyclic = interface procedure SetLink(L: ICyclic); end; TCyclic = class(TInterfacedObject, ICyclic) private FLink: ICyclic; public constructor Create; destructor Destroy; override; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; procedure SetLink(L: ICyclic); virtual; end; constructor TCyclic.Create; begin inherited; WriteLn('created'); end; destructor TCyclic.Destroy; begin WriteLn('destroyed'); inherited; end; function TCyclic._AddRef: Integer; begin Result := inherited _AddRef; WriteLn('referenced ' + IntToStr(Result)); end; function TCyclic._Release: Integer; begin Result := inherited _Release; WriteLn('released ' + IntToStr(Result)); end; procedure TCyclic.SetLink(L: ICyclic); begin FLink := L; end; procedure Main; var c: ICyclic; begin c := TCyclic.Create; c.SetLink(c); end; begin Main; ReadLn; end. ![]() ![]() created referenced 1 referenced 2 referenced 3 released 2 released 1 Хотя во всех (или почти всех) языках, где используется ARC, этот вопрос так или иначе решен. |
Сообщ.
#3638
,
|
|
|
Кстати да, есть ли безопасный способ разруливать циклияеские ссылки?
Добавлено Цитата Shaggy @ ничего не понял. что за иерархия? Работаешь через ссылку на интерфейс - получаешь одно поведение, работаешь через ссылку на объект - другое. И совершенно непонятно, зачем мне это нужно... Я так понимаю, что везде, кроме Delphi, подсчет ссылок ортогонален интерфейсам, наследованию и пр. механизмам ООП. |
![]() |
Сообщ.
#3639
,
|
|
тут следовало бы написать: гы, сколько пуканов порвалось!
![]() а вообще,создаётся впечатление, что я разговариваю с радио объясняю, а толку - ноль всё-равно делают по-своему Qraizer, тебе я вижу, не понравилось? так может оставишь этот снисходительный, менторский тон и поговорим нормально, как взрослые люди? ты вроде пишешь правильные и умные вещи... про С++ и у тебя почти получается писать про delphi, но временами ты выдаёшь такой... ну кроме как бредом назвать нельзя... Цитата MyNameIsIgor @ По его объяснениям (и по факту) счётчик здесь равен 1. Как и в Objective-C. Только в дельфях всё через... мне сказали, что конструкция make_shared<int>(42); выдаёт объект со счётчиком=1 далее следует присвоение, и следовательно... в моих словах отсутствует логика? а без последней фразы ты не мог, это да... молодец чё Цитата Qraizer @ На предмет порога вхождения в Дельфи ответ будет? а какого ответа ты ждёшь? в чём этот порог измеряется? %, попугаи? Цитата Qraizer @ У korvin-а пока получается лихо пороги переступать везде, кроме Дельфей ты считаешь это аргументом? у меня тоже с этим никаких проблем, и использование delphi мне никак не мешало Цитата korvin @ Угу, только shared_ptr -- 1) это другой объект, а не наш, 2) использование shared_ptr не ограничивает меня в способах построения иерархии своих классов. 1. так и у меня ссылки разные 2. интерфейсы меня тоже не ограничивают Цитата korvin @ Так это у вас надо спрашивать, у вас же разница есть. это было сравнение с++ и delphi подхода напишу прямо: не используй разные ссылки на один объект, не надо... это разные уровни если угодно, интерфейсы - более высокий уровень(совсем немного) да в delphi сделано так, в отдичие от других языков почему-то лезть в базу, например, в обход используемого фреймворка считается моветоном а тут всё в порядке? Цитата korvin @ Просто, как обычно, у Делфи свой путь. Куда-то далеко. это ты куда-то далеко идёшь Цитата D_KEY @ Работаешь через ссылку на интерфейс - получаешь одно поведение, работаешь через ссылку на объект - другое. интерфейсы используют, как раз, чтобы это(другое) поведение получить помнишь споры вокруг void и pointer? ничего общего не находишь? Добавлено Цитата korvin @ Я так понимаю, решение проблемы циклических ссылок тоже отдан на откуп программисту: да Цитата D_KEY @ Кстати да, есть ли безопасный способ разруливать циклияеские ссылки? насколько знаю, планируется ввести ARC(если я правильно понимаю, что это такое) и weak ref's может в ХЕ6 уже и есть, я не в курсе |
![]() |
Сообщ.
#3640
,
|
|
Цитата Shaggy @ 1. так и у меня ссылки разные На один и тот же объект. google: object identity. Цитата Shaggy @ интерфейсы меня тоже не ограничивают Ко многому можно привыкнуть, да. Скажи, почему нет интерфейсов для VCL-компонентов и как мне создать, скажем, свою Label, не наследуясь ни от TLabel, ни от любого из его предков? Цитата Shaggy @ почему-то лезть в базу, например, в обход используемого фреймворка считается моветоном Кем считается? Сейчас вроде модно наоборот, фреймворки считать моветоном. Цитата Shaggy @ а тут всё в порядке? Да, потому что тут везде всё в порядке, кроме Делфи. Цитата Shaggy @ насколько знаю, планируется ввести ARC(если я правильно понимаю, что это такое) ARC --- Automatic Reference Counting. И он никак не решает проблему циклических ссылок. Он ее скорее как раз создает. И у вас же уже есть ARC в интерфейсах, зачем вводить еще один какой-то? |
Сообщ.
#3641
,
|
|
|
Цитата Shaggy @ Цитата korvin @ Угу, только shared_ptr -- 1) это другой объект, а не наш, 2) использование shared_ptr не ограничивает меня в способах построения иерархии своих классов. 1. так и у меня ссылки разные 2. интерфейсы меня тоже не ограничивают У тебя один и тот же "вид" ссылок. По крайней мере явно. Как же тебе не мешают интерфейсы, если ты при их использовании должен непонятно почему думать о подсчете ссылок, хотя интерфейсы не имеют никакого отношения к управлению памятью. По крайней мере не должны. Связь-то какая между понятием интерфейса в ООП и механизмами управления памятью? Зачем так в Delphi сделали? Цитата интерфейсы используют, как раз, чтобы это(другое) поведение получить Т.е. интерфейсы в Delphi используют не как интерфейсы, а как механизм подсчета ссылок? Тогда их следовало назвать иначе. Цитата помнишь споры вокруг void и pointer? ничего общего не находишь? Эм. Пока нет. Раскрой тему. |
![]() |
Сообщ.
#3642
,
|
|
Цитата Shaggy @ weak ref's Указатели совсем вышли из моды? =) ![]() ![]() program Test; {$APPTYPE CONSOLE} uses SysUtils, Classes; type PICyclic = ^ICyclic; ICyclic = interface procedure PrintLn; procedure SetLink(L: PICyclic); function GetLink: PICyclic; end; TCyclic = class(TInterfacedObject, ICyclic) private FName: string; FLink: PICyclic; public constructor Create(Name: string); destructor Destroy; override; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; procedure PrintLn; virtual; procedure SetLink(L: PICyclic); virtual; function GetLink: PICyclic; virtual; end; constructor TCyclic.Create(Name: string); begin FName := Name; WriteLn('created'); end; destructor TCyclic.Destroy; begin WriteLn('destroyed'); inherited; end; function TCyclic._AddRef: Integer; begin Result := inherited _AddRef; WriteLn('referenced ' + IntToStr(Result)); end; function TCyclic._Release: Integer; begin Result := inherited _Release; WriteLn('released ' + IntToStr(Result)); end; procedure TCyclic.PrintLn; begin WriteLn(FName); end; procedure TCyclic.SetLink(L: PICyclic); begin FLink := L; end; function TCyclic.GetLink: PICyclic; begin Result := FLink; end; procedure Main; var c: ICyclic; begin c := TCyclic.Create('Foo'); c.SetLink(@c); c.GetLink^.PrintLn; end; begin Main; ReadLn; end. |
Сообщ.
#3643
,
|
|
|
Цитата Shaggy @ напишу прямо: не используй разные ссылки на один объект, не надо... Звучит как: "не используйте ООП, не надо"... |
![]() |
Сообщ.
#3644
,
|
|
Цитата korvin @ На один и тот же объект. тогда не понял. т.е. не может существовать двух ссылок(сырая и shared), указывающих на один объект? Цитата korvin @ Скажи, почему нет интерфейсов для VCL-компонентов потому-что интерфейсы появились позже VCL повсеместного введения плюшек последнего стандарта C++ я тоже не наблюдаю Цитата korvin @ Кем считается? Сейчас вроде модно наоборот, фреймворки считать моветоном. разжовываю: если ты используешь фреймворк, зачем лезть в обход? а если фреймворк - моветон, зачем ты его используешь? Цитата korvin @ Да, потому что тут везде всё в порядке, кроме Делфи. вот про это я и говорю: со своим уставом в чужой монастырь... где-то было обещано, что будет как "везде"? если ты учишь phyton, ты будешь возмущаться, что там не так как в С++? и продолжать писать код так же как в С++? Цитата korvin @ ARC --- Automatic Reference Counting значит неправильно понипал |
![]() |
Сообщ.
#3645
,
|
|
Давайте сделаем небольшое лирическое отступление (чтоб делфисты не чувствовали себя уникальными =)). Недавно наткнулся на еще один пример не совсем очевидного поведения в совсем другом языке. В Limbo структуры являются типами значений (как в C, Go и т.п.), например: ![]() ![]() Int: adt { val: int; }; Также существует ключевое слово ref, для создания ссылочных структур (ref можно использовать только с adt-типами), например: ![]() ![]() IntRef: type ref Int; x: IntRef; или просто ![]() ![]() x: ref Int; Однако, в следующем коде ![]() ![]() v := Int(1); r := ref v; ref v не вернет ссылку на v, как операция взятия адреса в других языках, она создаст новую ссылку на Int и скопирует туда значение v. Пруф: ![]() ![]() implement Command; include "sys.m"; sys: Sys; include "draw.m"; Command: module { init: fn(nil: ref Draw->Context, nil: list of string); }; init(nil: ref Draw->Context, nil: list of string) { sys = load Sys Sys->PATH; sys->print("ref = %d\n", <-spawnThread()); } Int: adt { val: int; }; spawnThread(): chan of int { c := chan of int; v := Int(1); r := ref v; sys->print("ref = %d, val = %d\n", r.val, v.val); spawn thread(c, r); sys->sleep(1000); sys->print("ref = %d, val = %d\n", r.val, v.val); r.val = 3; return c; } thread(out: chan of int, r: ref Int) { sys->sleep(500); r.val = 2; sys->sleep(1000); out <-= r.val; } ![]() ![]() ref = 1, val = 1 ref = 2, val = 1 ref = 3 |