Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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]

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

вот более подходящий пример из 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.007 c
2-1249308906
DevilDevil
2009-08-03 18:15
2009.10.04
Не получается сделать контекстное меню


15-1249115904
Alkid
2009-08-01 12:38
2009.10.04
Внимание, телефонная разводка


1-1218618200
dmitry_12_08_74
2008-08-13 13:03
2009.10.04
Подскажите, как определить, над каким окном находится мышь


2-1248863244
Tneduts
2009-07-29 14:27
2009.10.04
Символ ! !


15-1249325284
oldman
2009-08-03 22:48
2009.10.04
Да ну вас всех два





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский