Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.10.04;
Скачать: CL | DM;

Вниз

Вызов 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]

да нормальное поведение.

вот более подходящий пример из VCL

function 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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.016 c
15-1248973487
Северянин
2009-07-30 21:04
2009.10.04
Кто-нибудь сталкивался с КА?


2-1248674704
aza
2009-07-27 10:05
2009.10.04
ADO MS Jet прочитать не-коммитет данные


1-1218618339
gosha73
2008-08-13 13:05
2009.10.04
Вызов Release у формы


1-1218117173
RAndrey
2008-08-07 17:52
2009.10.04
Access Violation в потоке


2-1249023738
webpauk
2009-07-31 11:02
2009.10.04
Реакция на функциональные клавиши