
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.30] |
![]() |
|
Страницы: (245) « Первая ... 239 240 [241] 242 243 ... Последняя » ( Перейти к последнему сообщению ) |
![]() |
Сообщ.
#3601
,
|
|
ничем
|
![]() |
Сообщ.
#3602
,
|
|
Цитата Shaggy @ ничем Ну тогда вернись к моему первому примеру и объясни какого хрена там вызывается деструктор при выходе из процедуры Build. |
![]() |
Сообщ.
#3603
,
|
|
Цитата korvin @ Ну тогда вернись к моему первому примеру и объясни какого хрена там вызывается деструктор. твой пример не компилируется да, я могу, как ты говоришь, исправить "опечатки" и я это уже сделал, у меня всё работает но это уже получился мой пример приведи свой код, который компилируется и не работает |
![]() |
Сообщ.
#3604
,
|
|
Цитата Shaggy @ Ну тогда вернись к моему первому примеру и объясни какого хрена там вызывается деструктор при выходе из процедуры Build. приведи свой код, который компилируется и не работает Совсем запутали вы меня. ![]() ![]() program Test; {$APPTYPE CONSOLE} {$R *.res} uses SysUtils, Classes; type IWriter = interface procedure Write(S: string); procedure Flush; end; TWriter = class(TInterfacedObject, IWriter) private FLines: TStringList; public constructor Create; destructor Destroy; override; procedure Write(S: string); virtual; procedure Flush; virtual; end; constructor TWriter.Create; begin inherited; FLines := TStringList.Create; end; destructor TWriter.Destroy; begin FLines.Free; inherited; end; procedure TWriter.Write(S: string); begin FLines.Add(S); end; procedure TWriter.Flush; var i: Integer; begin for i := 0 to FLines.Count - 1 do WriteLn(FLines[i]); end; var W: TWriter; procedure Build(W: IWriter; S: string); begin W.Write(S); end; begin W := TWriter.Create; Build(W, 'Foo'); Build(W, 'Bar'); W.Flush; W.Free; ReadLn; end. Слегка перепутал объявление. Тем не менее делфизм не перестает быть делфизмом от этого. И ни от какого языка такого поведения не ожидается, т.к. не интерфейс хранит счетчик и управляет им, а объект. |
![]() |
Сообщ.
#3605
,
|
|
Цитата Shaggy @ На создаваемый объект ссылается то, что в данный момент владеет его Self-ом. Не знаю, кто этим является в Дельфях, наверно неосязаемое ничто, тогда вопросов, кроме уже поднятых не мною, нет. А вот в Плюсах этим нечто является отнюдь не ничто, а вполне осязаемый объект шаред-поинтера. Возможно временный, если речь идёт о, скажем, возврате по значению из функции, в любом случае инк при инициализации моего объекта и последующий дек в деструкторе временного не дадут счётчику упасть в нуль. Да здравствует семантика значений.Цитата Qraizer @ И создаваемый объект уже имеет счётчик 1, что однозначно отличает его состояние "только что создан" от "последняя ссылка освобождена". что хранит счётчик?... количество ссылок кто ссылается на создаваемый объект?... никто чему равен счётчик?... 0 В Дельфи что, в натуре считается нормальным, когда интерфейсы живут сами по себе безо всяких их реализующих объектов? Не запутались там в своих ссылках ещё, нет? Снова вопрошаю: на кой хрен считать интерфейсы? |
Сообщ.
#3606
,
|
|
|
Цитата korvin @ Цитата D_KEY @ Как это никто не ссылается, если ты обращаешься к нему? 0 возможен только как промежуточное состояние внутри некоторой операции со ссылкой (в процессе создания и возможного удаления удаления объекта). Объект с 0 счётчиком не должен существовать. Знаешь как они докатились до жопы такой? Вот смотри: ![]() ![]() procedure Foo(x: IInterface); ... Foo(TInterfacedObject.Create); Объект создается до вызова процедуры, счетчик = 0, передается в процедуру по интерфейсу, счетчик увеличивается до единицы. Процедура завершается, счетчик уменьшается до нуля, объект уничтожается. Все как бы хорошо. Но, как следствие, с полями (и, видимо, с переменными) это не прокатывает. Кстати, что происходит в C++-ных ARC-объектах в таких случаях (создание in-place и тут же передача в процедуру)? В C++ за то, будет у тебя подсчет или нет, отвечают ссылки. Соответственно, если принимаешь на вход shared_ptr, то утечки не будет. Если принимаешь сырой указатель и кто-то передал туда результат new, то будет утечка. |
![]() |
Сообщ.
#3607
,
|
|
![]() #3566 1. W:IWriter; а W.Free; убрать 2. procedure Build(W:TWriter; S:string); 3. ![]() ![]() TNoRefObject = class(TObject, IInterface) protected function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; end; function TNoRefObject.QueryInterface(const IID: TGUID; out Obj): HResult; begin if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE; end; function TNoRefObject._AddRef: Integer; begin Result := MAXINT; end; function TNoRefObject._Release: Integer; begin Result := MAXINT; end; и TWriter = class(TNoRefObject, IWriter) выбор варианта зависит от того, что же ты на самом деле хотел Добавлено Цитата Qraizer @ На создаваемый объект ссылается то, что в данный момент владеет его Self-ом. Не знаю, кто этим является в Дельфях, наверно неосязаемое ничто, тогда вопросов, кроме уже поднятых не мною, нет. то, что ссылается, им не владеет. т.е. не контролирует время жизни Цитата Qraizer @ В Дельфи что, в натуре считается нормальным, когда интерфейсы живут сами по себе безо всяких их реализующих объектов на основании чего был сделан этот вывод? это физически неозможно Цитата Qraizer @ Не запутались там в своих ссылках ещё, нет? а вы в своих? Цитата Qraizer @ Снова вопрошаю: на кой хрен считать интерфейсы? считаем ссылки, сколько раз запросили интерфейс(любой) столько и ссылок имеется understand? |
Сообщ.
#3608
,
|
|
|
Shaggy, ну идиотизм же. Зачем ты это защищаешь?
|
![]() |
Сообщ.
#3609
,
|
|
конструктивненько...
в чём принципиальное отличие от shared_ptr? |
Сообщ.
#3610
,
|
|
|
А что мы на последних страницах обсуждаем? И вполне себе конструктивно было...
А shared_ptr лучше явным поведением, отсутствием привязки к иерархии и каким-то другим языковым конструкциям. Это вообще обычный библиотечный класс. |
![]() |
Сообщ.
#3611
,
|
|
Цитата Shaggy @ Воот. А должен. Никто не владеет, некому и считать ссылки. Отсюда в частности и обсуждаемые проблемы. Сырыми поинтерами в Сях/Плюсах тоже никто не владеет, так что знаем, каково это. то, что ссылается, им не владеет. т.е. не контролирует время жизни |
![]() |
Сообщ.
#3612
,
|
|
Цитата Shaggy @ выбор варианта зависит от того, что же ты на самом деле хотел Я хотел простые интерфейсы, как везде. Цитата Shaggy @ ![]() ![]() TNoRefObject = class(TObject, IInterface) ... О чем и речь, вместо наполнения пустого ящика нужными вещами, берем ящик с хламом и предварительно его вычищаем. Delphi-way, че. Цитата Shaggy @ в чём принципиальное отличие от shared_ptr? Тем, что shared_ptr не навязывает моему классу и моему интерфейсу какие-либо методы и поведение и я (в моем случае) могу даже не вспоминать о его существовании. А если он мне понадобится --- не заботиться о каких-то служебных методах для его корректной работы. Добавлено Цитата Shaggy @ считаем ссылки, сколько раз запросили интерфейс(любой) столько и ссылок имеется understand? И на кой черт нам считать ссылки на интерфейсы, если время жизни --- это характеристика объекта, лежащего за этими интерфейсами? Добавлено Кроме того, если я уверен, что в процедуре, которая требует интерфейс (такая вот библиотечная процедура, множественного наследования-то нет, вот, чтобы не ограничивать пользователя на реализацию объекта, она и просит интерфейс), не сохранится ссылок, то зачем мне вообще в данном случае сталкиваться со счетчиком ссылок (но в других случаях я хочу, чтоб ссылки считались)? ![]() ![]() Foo(x); // -- сюда я хочу передать "сырую ссылку" Bar(x); // -- а сюда "инкрементированую" // потому что здесь я "потеряю" ссылку на x Как быть? |
Сообщ.
#3613
,
|
|
|
Кстати, в C++ обычно передают shared_ptr по ссылке, чтоб избежать лишней работы со счетчиками.
![]() ![]() void foo(const shared_ptr<IFoo> &ptr) В Delphi, как я понимаю, так не сделать? Добавлено korvin, единственное что, у нас иногда приходится возиться с shared_from_this. В Delphi, видимо, не придётся ничего дополнительного делать. |
![]() |
Сообщ.
#3614
,
|
|
Не ну Дельфи-то понять можно, korvin. Унаследовав COM к себе и приняв его вынужденные ограничения, Дельфи с COM-интерфейсами иначе никак и не поступить. Хочешь считать не интерфейсы, а объекты, перекрывай счётчики и реализуй сообразно. Другое дело, что COM-интерфейсы - это не те интерфейсы, которые первыми приходят на ум, когда слышишь "интерфейс". И почему, кроме COM, никаких других Дельфи не даёт, вот это непонятно.
Добавлено Хотя если рассуждать здраво, наплодить ещё одну сущность в довесок к имеющимся, так Дельфи ещё тяжелее станет, а профям и так сойдёт. |
![]() |
Сообщ.
#3615
,
|
|
Цитата D_KEY @ А shared_ptr лучше явным поведением, отсутствием привязки к иерархии и каким-то другим языковым конструкциям. Цитата korvin @ Тем, что shared_ptr не навязывает моему классу и моему интерфейсу какие-либо методы и поведение и я (в моем случае) могу даже не вспоминать о его существовании. А если он мне понадобится --- не заботиться о каких-то служебных методах для его корректной работы. он лучше только тем, что "прозрачный" а служебные методы уже реализовали за тебя Цитата Qraizer @ А должен с чего вдруг? Цитата korvin @ Я хотел простые интерфейсы, как везде. первый вариант а вообще, хранить и использовать две ссылки(с подсчётом ссылок и сырую) на одну сущьность, это нормально? C++way? Цитата korvin @ Кроме того, если я уверен, что в процедуре, которая требует интерфейс (такая вот библиотечная процедура, множественного наследования-то нет, вот, чтобы не ограничивать пользователя на реализацию объекта, она и просит интерфейс), не сохранится ссылок, то зачем мне вообще в данном случае сталкиваться со счетчиком ссылок (но в других случаях я хочу, чтоб ссылки считались)? ![]() ![]() procedure Build(const W: IWriter; S: string); addref и release дёргаться не будут Цитата korvin @ О чем и речь, вместо наполнения пустого ящика нужными вещами, берем ящик с хламом и предварительно его вычищаем. Delphi-way, че. TObject, пустее просто нет Цитата korvin @ И на кой черт нам считать ссылки на интерфейсы, если время жизни --- это характеристика объекта, лежащего за этими интерфейсами? да объекта, и? |