Форум: "Прочее";
Текущий архив: 2009.10.04;
Скачать: [xml.tar.bz2];
ВнизВызов Free (Destroy) внутри метода объекта Найти похожие ветки
← →
pasha_golub © (2009-08-03 18:36) [0]Тут сабжевый холливорчик завязался. Ситуация:
procedure SomeProc;
begin
<do smth>;
if SomeIllegalCondition then Free;
end;
Моя позиция такова, что это имеет право быть. Ибо в самой VCL:
procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;
Шо ничто иное как вызов деструктора внутри метода объекта.
Я подозреваю, что где-то в хелпе об этом написано. Однако есть у кого коротко и по делу?
← →
StriderMan (2009-08-03 18:38) [1]да нормальное поведение.
вот более подходящий пример из VCLfunction TInterfacedObject._Release: Integer;
begin
Result := InterlockedDecrement(FRefCount);
if Result = 0 then
Destroy;
end;
← →
Dimka Maslov © (2009-08-03 18:40) [2]Минус такого подхода в том, что вызывающая процедура (при наличии таковой) не будет знать, что объект уже уничтожен и при повторной попытке уничтожить объект произойдет AV.
← →
Palladin © (2009-08-03 18:42) [3]
> [2] Dimka Maslov © (03.08.09 18:40)
Это минус и деструктора тоже. И Free.
← →
Dimka Maslov © (2009-08-03 18:45) [4]
> Palladin © (03.08.09 18:42) [3]
Вот поэтому желательно, чтобы объект уничтожал тот, кто его создал. Хотя, как говорится, всё можно, только осторожно.
← →
Palladin © (2009-08-03 18:47) [5]Хм, не вижу связи между инициатором уничтожения и вызовом деструктора из метода.
← →
Dimka Maslov © (2009-08-03 18:48) [6]А она есть :))
← →
Palladin © (2009-08-03 18:49) [7]Это тебе не суслик. Следуя твоей логике метод Free тоже нужно искоренить. Потому что "желательно, чтобы объект уничтожал тот, кто его создал".
← →
StriderMan (2009-08-03 18:49) [8]
> Вот поэтому желательно, чтобы объект уничтожал тот, кто его создал.
VCL явно не придерживается такой концепции.
Вот примеры:
1. Сабж.
2.TComponent.Create(Owner)
- Owner разрушит
3.TControl.Parent :=
- Parent тоже попытается разрушить
4.TThread.FreeOnTerminate
← →
pasha_golub © (2009-08-03 18:50) [9]
> А она есть :))
Это про суслика!
> Dimka Maslov © (03.08.09 18:40) [2]
>
> Минус такого подхода в том, что вызывающая процедура (при
> наличии таковой) не будет знать, что объект уже уничтожен
> и при повторной попытке уничтожить объект произойдет AV.
>
А сделать нечто подобное FreeAndNill возможно изнутре? Там где неонка...
← →
Palladin © (2009-08-03 18:51) [10]
> А сделать нечто подобное FreeAndNill возможно изнутре?
Нет. Сколько раз уже эта тема обсасывалась... )
← →
Dimka Maslov © (2009-08-03 18:52) [11]Хорошо, переформулируем фразу так:
"желательно, чтобы деструктор объекта вызывался процедурой(объектом), в которой был вызван его конструктор".
← →
Dimka Maslov © (2009-08-03 18:58) [12]
> VCL явно не придерживается такой концепции.
Пускай не придерживается. Это вопрос личных предпочтений. Уверен в себе - можешь поступать как хочешь.
> А сделать нечто подобное FreeAndNill возможно изнутре?
Только если в самом объекте держать список всех ссылок на сам объект. Явно нереально.
← →
StriderMan (2009-08-03 18:58) [13]
> Хорошо, переформулируем фразу так:
> "желательно, чтобы деструктор объекта вызывался процедурой(объектом),
> в которой был вызван его конструктор".
Да как ни переформулируй, в VCL этот принцип не выполняется.
Я абсолютно согласен, что гораздо надежнее самостоятельно контролировать где и что разрушается, однако коль скоро VCL этого не придерживается, программистам приходится подстраиваться под нее
← →
StriderMan (2009-08-03 19:00) [14]
> Пускай не придерживается. Это вопрос личных предпочтений. Уверен в себе - можешь поступать как хочешь.
VCL это не вопрос личных предпочтений, а основа почти всех проектов на Делфи. Хочешь не хочешь а она есть
← →
Palladin © (2009-08-03 19:00) [15]
> [13] StriderMan (03.08.09 18:58)
ты не путай теплое с мягким... когда ты создаешь компонент выполняется его агрегация во владельца(родителя) и он вправе его освобождать... это никак не противоречит ООП...
← →
Юрий Зотов © (2009-08-03 19:02) [16]> pasha_golub © (03.08.09 18:36)
Ничего не подозревая о засаде, вызываем метод SomeProc из другой процедуры, в которой после вызова SomeProc есть прямое или опосредованное обращение к полям объекта.
Все вполне законно - а получаем AV. И чешем репу в непонятках. Кто ж мог знать, что разработчик класса так изгальнулся?
Дурной это тон, Паша, когда объект сам себя убивает. Опасно. А интерфейсы - это совсем другое дело, там счетчик ссылок безопасность обеспечивает.
← →
StriderMan (2009-08-03 19:03) [17]
> это никак не противоречит ООП...
а я и не говорю что, противоречит. Как и сабж
← →
Palladin © (2009-08-03 19:09) [18]
> [17] StriderMan (03.08.09 19:03)
А так же и не противоречит и докторине "ручного" особождения объектов. Нет ничего зазорного в том, что объекты в составе TObjectList освобождаются. Это никак не противоречит "я тебя породил я тебя и убью".
← →
Юрий Зотов © (2009-08-03 19:09) [19]> StriderMan (03.08.09 18:49) [8]
> Owner разрушит
> Parent тоже попытается разрушить
Не-а, не попытается. При разрушении объект автоматически исключается из списка Controls.
Из списка Components, кстати, тоже - так что если Parent объект убил, то Owner об этом объекте уже ничего не знает, он уже вообще не Owner.
← →
Dimka Maslov © (2009-08-03 19:09) [20]
> StriderMan (03.08.09 18:58) [13]
VCL не придерживается данного принципа только там, где разработчики VCL уверены в том, что никто другой, кроме самого объекта, уничтожать себя не будет.
> StriderMan (03.08.09 19:00) [14]
Другими словами, надо уничтожать объекты где попало, а потом бороться с AV и утечками памяти? Нет. Надо осознанно подходить к данному вопросу. И пользоваться тем способом, который предпочтительнее в данной конкретной ситуации. Что же касается VCL — основы почти всех проектов на Делфи, она, при желании и за исключением особо тонких мест, поддаётся обработке напильником.
← →
StriderMan (2009-08-03 19:09) [21]
> А интерфейсы - это совсем другое дело, там счетчик ссылок безопасность обеспечивает.
Вот только если программист не знал что класс этот реализует некие интерфейсы, а где-то в недрах чужого кода некая интерфейсная переменная внезапно получила ссылку на этот объект и разрушила его. Программист опять же получит AV.
← →
StriderMan (2009-08-03 19:11) [22]
> Другими словами, надо уничтожать объекты где попало, а потом бороться с AV и утечками памяти?
нет. Этим надо пользоваться осторожно
> VCL не придерживается данного принципа только там, где разработчики VCL уверены в том, что никто другой, кроме самого объекта, уничтожать себя не будет.
так а что мешает программисту использовать такой подход, если он уверен что никто другой... ?
← →
Palladin © (2009-08-03 19:12) [23]
> [21] StriderMan (03.08.09 19:09)
Смешаный режим работы с наследниками TInterfacedObject сам по себе абсолютно не привествуется. И это будет ошибкой того самого программиста.
← →
Dimka Maslov © (2009-08-03 19:14) [24]
> так а что мешает программисту использовать такой подход,
> если он уверен что никто другой... ?
Ничего не мешает. Буквально вообще ничего.
← →
StriderMan (2009-08-03 19:15) [25]
> Смешаный режим работы с наследниками TInterfacedObject сам по себе абсолютно не привествуется. И это будет ошибкой того самого программиста.
перекрываем _AddRef и _Release >> вуаля! Всё безопасно!
← →
Mystic © (2009-08-03 19:18) [26]Да, такая ситуация, как описана в сабже, возможна. Но требует более тщательного проектирования времени жизни объектов.
> А сделать нечто подобное FreeAndNill возможно изнутре? Там
> где неонка...
Это называется weak references (слабые ссылки). Стандартного такого механизма в Delphi нет. Тут есть описание С++ механизма, который можно перенести на Delphi
http://www.sources.ru/wiki/doku.php?id=doc:cpp:boost:shared_ptr
← →
jack128_ (2009-08-03 19:54) [27]
> Смешаный режим работы с наследниками TInterfacedObject сам
> по себе абсолютно не привествуется. И это будет ошибкой
> того самого программиста.
ну сами разрабы дельфи написали такой ужос, как TXMLDocument...
← →
pasha_golub © (2009-08-03 20:04) [28]
> Нет. Сколько раз уже эта тема обсасывалась... )
Я не обсасывал... Не успел.
← →
pasha_golub © (2009-08-03 20:05) [29]
> StriderMan (03.08.09 19:09) [21]
>
>
> > А интерфейсы - это совсем другое дело, там счетчик ссылок
> безопасность обеспечивает.
>
> Вот только если программист не знал что класс этот реализует
> некие интерфейсы, а где-то в недрах чужого кода некая интерфейсная
> переменная внезапно получила ссылку на этот объект и разрушила
> его. Программист опять же получит AV.
+100
Убил бы. Нарвался на сью граблю. Чуть моск не поломал
← →
pasha_golub © (2009-08-03 20:07) [30]
> Palladin © (03.08.09 19:12) [23]
>
>
> > [21] StriderMan (03.08.09 19:09)
>
> Смешаный режим работы с наследниками TInterfacedObject сам
> по себе абсолютно не привествуется. И это будет ошибкой
> того самого программиста.
Однако в мануале рекоммендуется использовать TInterfacedObject как прародителя, тудытегоразтудыт...
← →
pasha_golub © (2009-08-03 20:08) [31]
> jack128_ (03.08.09 19:54) [27]
> ну сами разрабы дельфи написали такой ужос, как TXMLDocument.
> ..
Жень, поподробней могешь для аутсайдеров?
← →
oxffff © (2009-08-03 21:19) [32]
> Mystic © (03.08.09 19:18) [26]
> Да, такая ситуация, как описана в сабже, возможна. Но требует
> более тщательного проектирования времени жизни объектов.
>
>
>
> > А сделать нечто подобное FreeAndNill возможно изнутре?
> Там
> > где неонка...
>
>
> Это называется weak references (слабые ссылки). Стандартного
> такого механизма в Delphi нет. Тут есть описание С++ механизма,
> который можно перенести на Delphi
Слабая ссылка в delphi делается элементарно.
← →
тимохов © (2009-08-03 22:44) [33]
> oxffff © (03.08.09 21:19) [32]
> Слабая ссылка в delphi делается элементарно.
нет, ты не прав.
← →
Юрий Зотов © (2009-08-03 22:49) [34]> тимохов © (03.08.09 22:44) [33]
+5 :0)
← →
jack128_ (2009-08-03 22:59) [35]
>
> Жень, поподробней могешь для аутсайдеров?
TXMLDocument ведет подсчет ссылок, если ему в конструктор передали nil, иначе ведет ся как компонент. В ОЧумелых руках страшная вещь может получиться.
← →
тимохов © (2009-08-03 23:00) [36]
> Юрий Зотов © (03.08.09 22:49) [34]
>
> > тимохов © (03.08.09 22:44) [33]
>
> +5 :0)
Мне тоже понравилось. Главное - как я точно сказал! А какая аргументация!!! Все бы так объяснялись.
))
← →
Дмитрий С © (2009-08-04 07:26) [37]
> тимохов © (03.08.09 23:00) [36]
Элементарно не значит просто. Поэтому...
← →
oxffff © (2009-08-04 08:30) [38]
> тимохов © (03.08.09 22:44) [33]
>
> > oxffff © (03.08.09 21:19) [32]
> > Слабая ссылка в delphi делается элементарно.
>
>
> нет, ты не прав.
Приветствую, Дмитрий.
1. WeakRefStuff=Pointer(Iunknown).
2. class=class(TinterfacedObject,WeakInterface)
function WeakInterface._Addref=WeakAddref
function WeakInterface._Release=WeakRelease
function WeakAddref
function WeakRelease
3. Делегация реализации аггрегированному объекту с указанием семантики копирования.
4. Динамическое создание интерфейса.
5. И др.
6. Использование GC в native delphi
http://cc.embarcadero.com/Item/21646
http://cc.embarcadero.com/Item/26716
Теперь жду от тебя не меньшей аргументации.
← →
brother © (2009-08-04 08:35) [39]> Теперь жду от тебя не меньшей аргументации.
> 5. И др.
убойный аргумент ;)
← →
oxffff © (2009-08-04 08:36) [40]
> brother © (04.08.09 08:35) [39]
ГЫ ГЫ.
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2009.10.04;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.007 c