Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.10.21;
Скачать: [xml.tar.bz2];

Вниз

FreeAndNil   Найти похожие ветки 

 
mike_zav   (2007-09-21 17:37) [0]

В каких случаях применяют FreeAndNil? А в каких просто .Free?
Зачем это нужно? Если можно с примером.


 
Ega23 ©   (2007-09-21 17:40) [1]

FreeAndNil(obj) применяют в тех случаях, когда впадлу написать
obj.Free;
obj:=nil;


> Зачем это нужно?


Это нужно для того, чтобы в одном случае ссылка стала равной nil, а в другом - нет.

З.Ы. Ни разу FreeAndNil не использовал.


 
Инс ©   (2007-09-21 17:42) [2]


> В каких случаях применяют FreeAndNil?

Например, если в будущем понадобится проверить, уничтожен ли экземпляр, на который ссылается данная переменная/поле класса.


 
stanislav ©   (2007-09-21 17:45) [3]

http://delphimaster.net/view/2-1190379982/


 
Leonid Troyanovsky ©   (2007-09-21 17:48) [4]


> mike_zav   (21.09.07 17:37)  

> Зачем это нужно? Если можно с примером.

Да, собс-но, не нужно. Ну, может, писать короче.
Но, от неприятностей оно не спасет.

--
Regards, LVT.


 
Anatoly Podgoretsky ©   (2007-09-21 18:55) [5]

> mike_zav  (21.09.2007 17:37:00)  [0]

Никогда не применял, за ненадобностью подобной функций, которая была сделана Борландом для забывчивых и неумеющих. Наличие подобной функции как правило говорит о недостатках в программе.


 
Anatoly Podgoretsky ©   (2007-09-21 18:56) [6]

> Инс  (21.09.2007 17:42:02)  [2]

Переменная это недостаток, а поля можно и нужно делать контролируемыми.


 
mike_zav   (2007-09-21 19:34) [7]

Бррр.. так я и не понял одного, это должно спасти от ложного срабатывания Assign, при уже уничтоженном объекте?


 
Сергей М. ©   (2007-09-21 19:39) [8]


> mike_zav   (21.09.07 19:34) [7]



> это должно спасти .. ?


А куда ему деться с подводной лодки ?)

"Согласие есть продукт при полном непротивлении сторон" (С)

FreeAndNil "нилит" переменную, а Assigned, видя этот "нил", согласен и имеет все основания выдать False.


 
Инс ©   (2007-09-21 20:05) [9]


> Никогда не применял, за ненадобностью подобной функций,
> которая была сделана Борландом для забывчивых и неумеющих.
> Наличие подобной функции как правило говорит о недостатках
> в программе.

Ну, значит Borland сами забывчивы и неумеющие :) Например, в модуле Graphics - используется повсеместно. Например класс TBitmap метод GetCanvas вначале проверяет на равенство поля FCanvas nil, и только потом в случае успешной проверки создает экземпляр TCanvas. А когда Canvas становится невалидным (например, после вызова Dormant) - уничтожает ее и обнуляет ссылку. Теперь, если вдруг кто-либо обратится к свойству Canvas, снова вызывается GetCanvas, проверяется на nil и т.д.
Т.е. благодаря обнулению ссылок можно создавать вложенные объекты только по требованию.


 
Anatoly Podgoretsky ©   (2007-09-21 20:11) [10]

> Инс  (21.09.2007 20:05:09)  [9]

FCanvas это контролируемая вещь, которую не обойдешь, а обнулить я предпочту явно. Никто же не утверждает, что нельзя присваивать nil, только на пользовательском уровне, особенно для переменных это говорит о желании повторного использования переменной со всеми вытекающими от этого последствиями.


 
Инс ©   (2007-09-21 20:14) [11]


> [10] Anatoly Podgoretsky ©   (21.09.07 20:11)

Прошу прощения, не совсем понял вашу последнюю мысль...


 
Anatoly Podgoretsky ©   (2007-09-21 20:15) [12]

> Инс  (21.09.2007 20:14:11)  [11]

Что именно, я же много о чем говорил.
Может термин повторное использование переменных?


 
Инс ©   (2007-09-21 20:18) [13]


> FCanvas это контролируемая вещь, которую не обойдешь, а
> обнулить я предпочту явно.

Несколько раз перечитал это предложение, не могу понять смысл...


> Может термин повторное использование переменных?

Нет, с этим как раз все понятно.


 
Инс ©   (2007-09-21 20:21) [14]

А, все, кажется понял...


 
Anatoly Podgoretsky ©   (2007-09-21 20:21) [15]

> Инс  (21.09.2007 20:18:13)  [13]

> FCanvas это контролируемая вещь, которую не обойдешь, а
> обнулить я предпочту явно.

> Несколько раз перечитал это предложение, не могу понять смысл...

Все равно не понятно, что именно непонятно.
Что такое контролируемое или почему явно?


 
Anatoly Podgoretsky ©   (2007-09-21 20:23) [16]

Функция FreeAndNil сравни функии IncDay


 
Anatoly Podgoretsky ©   (2007-09-21 20:24) [17]

> Инс  (21.09.2007 20:21:14)  [14]

Не если не понял не стесняйся уточнить.


 
Инс ©   (2007-09-21 20:25) [18]

Комментирую [10]:


> только на пользовательском уровне

Ну, мы же вроде не только пользователи, но и программисты, иногда классы приходится писать самому. А следовательно может возникнуть подобная ситуация. И тогда можно действовать подобным образом. У меня даже когда-то было что-то похожее, но вот пока найти не могу, привел бы пример. А значит слишком категоричное утверждение о забывчивости и неумении становится не совсем верным. Случаи ведь разные бывают.


 
Anatoly Podgoretsky ©   (2007-09-21 20:35) [19]

У нас есть разделение, есть писатели компонент, а есть их пользователи и это даже может быть один и тот-же человек.
Утверждение не категоричное, а относится к культуре проектирования.
Надо предусмотреть меры по защите члена от непреднамеренного изменения за пределами класса, изоляция прямого доступа. Вот это и есть контролирование поведения на "системном" уровне.
Разница между


> public
>     X: type;


и

private
   FX: type;
published
   X: type read FX write FX;


большая и тем более для

private
   FX: type;
   function GetX: type;
   procedure SetX(X: type);
published
   X: type read FX write FX;


Практически весь VCL пропитан этим.
И в третьем случае полный контроль над членом класса, без утечек и непридвиденного измения.

X := TBitmap.Create;
X := TBitmap.Create;
X := TBitmap.Create;
X := TBitmap.Create;
X := nil;


Никаких утечек, несмотря что нет разрушения старого значения.


 
Anatoly Podgoretsky ©   (2007-09-21 20:36) [20]

Очепятка в третьем примере

published
  X: type read GetX write SetX;


 
Инс ©   (2007-09-21 20:41) [21]


> Очепятка в третьем примере

Я догадался, все в порядке :)

Как считаете, в данной дискусии был раскрыт вопрос автора или нет? Истина найдена? Итоги подводить можно?


 
Anatoly Podgoretsky ©   (2007-09-21 20:44) [22]

> Инс  (21.09.2007 20:41:21)  [21]

Я думаю был раскрыт.
Функция была изобретена для ленивых и она не обязательна к использованию, более того она провоцирует на не совсем безопасный код.

Есть конечно и не согласные с этим, но на этих только время подействует, когда станут мудрее.
Борланд очень много колокольчиков включила в последнии версии, где после 5 версии они посыпались горой, вместо создания действительно необходимых функций.


 
Инс ©   (2007-09-21 20:52) [23]

Ясно, пациент безнадежен :) Ладно, дальше спорить не буду. Вот это разве что прокомментирую.

> Функция была изобретена для ленивых и она не обязательна к
> использованию, более того она провоцирует на не совсем безопасный код

Не обязательна. Можно написать в две строчки. А насчет провоцирует на небезопасный код - так любое техническое средство в руках дикаря - груда металлолома. Вы просто не хотите поверить в случай, что время жизни объекта, на который ссылается некий идентификатор, может подчиняться достаточно сложному закону (из-за оптимизации, например. Нужен - создаем, как только перестает быть нужен - уничтожаем), и тогда нет ничего проще, чем при уничтожении объекта всего лишь обнулить ссылку.


 
Anatoly Podgoretsky ©   (2007-09-21 21:03) [24]

> Инс  (21.09.2007 20:52:23)  [23]

Не будем рассматривать особые случае, я оперирую более общей сущностью.


 
Инс ©   (2007-09-21 21:09) [25]


> Не будем рассматривать особые случае, я оперирую более общей
> сущностью.

Я спорю только с категоричностью утверждения. Говорю, что в таком виде вывод не верный, есть оговорки. Вот и пытаюсь их обговорить...


 
Anatoly Podgoretsky ©   (2007-09-21 21:12) [26]

> Инс  (21.09.2007 21:09:25)  [25]

Вывод о категоричности неверный, это только кажется (стиль у меня такой). Я готов рассматривать и альтернативные варианты, вплоть до правомерности и ламерского кода.


 
Инс ©   (2007-09-21 23:10) [27]

И снова возвращаясь к первоначальной постановке вопроса... Мне тут статейку одну по этой теме подсказали (спасибо DRON ;-) ), немного трудновато написано, но все равно рекомендую:
http://blogs.codegear.com/abauer/2006/11/01/28852


 
Anatoly Podgoretsky ©   (2007-09-22 11:56) [28]

> Инс  (21.09.2007 23:10:27)  [27]

Полемика NilAndFree или FreeAndNil ведется с момента появления функции.
Так же как и необходимость в данной функции.
Все остаются при своих.


 
oxffff ©   (2007-09-22 13:22) [29]


> Anatoly Podgoretsky ©   (22.09.07 11:56) [28]
> > Инс  (21.09.2007 23:10:27)  [27]
>
> Полемика NilAndFree или FreeAndNil ведется с момента появления
> функции.
> Так же как и необходимость в данной функции.
> Все остаются при своих.


А спор о чем?


 
Anatoly Podgoretsky ©   (2007-09-22 13:31) [30]

> oxffff  (22.09.2007 13:22:29)  [29]

Спор ведется о буквах, мол неправильное название и спор ведется уже не один год.


 
oxffff ©   (2007-09-22 13:34) [31]


> Anatoly Podgoretsky ©   (22.09.07 13:31) [30]
> > oxffff  (22.09.2007 13:22:29)  [29]
>
> Спор ведется о буквах, мол неправильное название и спор
> ведется уже не один год.


Дык и текущая реализация не идеальна.

Ловим AV.
:)

procedure TForm1.Button1Click(Sender: TObject);
var a:^TObject;
begin
a:=nil;
Freeandnil(a^);
end;


 
Anatoly Podgoretsky ©   (2007-09-22 13:44) [32]

> oxffff  (22.09.2007 13:34:31)  [31]

Реализаций по сути две
FreeAndNil и NilAndFree

Реализация функции мне не нравится по следующей причине

procedure FreeAndNil(var Obj);

Видим уход от типизации и соответсвенно невозможность проверить еще на этапе компиляции.
Почему они так поступили конечно понятно, но я бы их расстрелял.
Вот если бы они реализовали так

procedure FreeAndNil(var Obj: TObject);

То таких бы претензий у меня не было. Компилятор бы просто не пропустил многие ошибки.


 
Anatoly Podgoretsky ©   (2007-09-22 13:46) [33]

Кстати с Free такой проблемы просто нет, там все в рамках идеологии Паскаля и реализация правильная.
Историю как появилась данная и другие подобные функции я помню, как все развивалось в Борланде в сторону попсовости, в сторону популизма.


 
oxffff ©   (2007-09-22 13:51) [34]


> Anatoly Podgoretsky ©   (22.09.07 13:44) [32]
> > oxffff  (22.09.2007 13:34:31)  [31]
>
> Реализаций по сути две
> FreeAndNil и NilAndFree
>
> Реализация функции мне не нравится по следующей причине
>
> procedure FreeAndNil(var Obj);
>
> Видим уход от типизации и соответсвенно невозможность проверить
> еще на этапе компиляции.
> Почему они так поступили конечно понятно, но я бы их расстрелял.
>
> Вот если бы они реализовали так
>
> procedure FreeAndNil(var Obj: TObject);
>
> То таких бы претензий у меня не было. Компилятор бы просто
> не пропустил многие ошибки.


А мне собственно не понятно почему они поставили untyped параметр?


 
Anatoly Podgoretsky ©   (2007-09-22 13:58) [35]

> oxffff  (22.09.2007 13:51:34)  [34]

> А мне собственно не понятно почему они поставили untyped параметр?

Посмотри исходные коды, может станет понятно.
Но с тезисом, что это бардак и некомпетентность ты в принципе согласен?


 
oxffff ©   (2007-09-22 14:16) [36]


> Anatoly Podgoretsky ©   (22.09.07 13:58) [35]
> > oxffff  (22.09.2007 13:51:34)  [34]
>
> > А мне собственно не понятно почему они поставили untyped
> параметр?
>
> Посмотри исходные коды, может станет понятно.
> Но с тезисом, что это бардак и некомпетентность ты в принципе
> согласен?


С тезисом я согласен.
Действительно FreeAndNil(var Obj: TObject) более строгое определение.

Понял ваш намек. Чтобы не мучиться с приведение var параметров.

Тогда. Вопрос.

Почему бы не добавить поддержку неявного приведения var параметров.

Если Tobject и pointer "совместимы"
Если потомок и родитель "совместимы"

Почему тогда  ссылка(var параметр) на эти типы не совместимы.

Например мы же можем спокойно присваивать потомков Tobject к pointer и наоборот. Почему не сделать такое неявное приведение для var параметров.
Сейчас в голову не приходит каких либо проблем с этим. IMHO.


 
oxffff ©   (2007-09-22 14:21) [37]

Почему выходит
Types of actual and formal var parameters must be identical?

Для

procedure abc(var a:Tobject);
begin
end;

procedure TForm1.Button1Click(Sender: TObject);
var a:tControl;
begin
abc(a);
end;

К каким проблемам это может привести?


 
Anatoly Podgoretsky ©   (2007-09-22 14:27) [38]

> oxffff  (22.09.2007 14:21:37)  [37]

В данном случае ни к каким, поскольку tControl наследник от Tobject и обладает всеми его методами и полями. Вот наоборот нельзя.


 
oxffff ©   (2007-09-22 14:32) [39]


> Anatoly Podgoretsky ©   (22.09.07 14:27) [38]
> > oxffff  (22.09.2007 14:21:37)  [37]
>
> В данном случае ни к каким, поскольку tControl наследник
> от Tobject и обладает всеми его методами и полями. Вот наоборот
> нельзя.


И я о том же. Только почему компилятор не пропускает это?

В чем причина этого ограничения.

Пойдем дальше. Почему ругается?

procedure abc(var a:Tobject);
begin
end;

procedure TForm1.Button1Click(Sender: TObject);
var a:pointer;
begin
abc(a);
end;

Tobject и pointer "совместимы". А передача как var параметра накладывает самые строгие ограничения.

Не считаете ли вы это упущением?


 
Anatoly Podgoretsky ©   (2007-09-22 14:36) [40]

> oxffff  (22.09.2007 14:32:39)  [39]

Может из-за var
В этом случае да, параметры не идентичны.


 
oxffff ©   (2007-09-22 14:44) [41]


> Anatoly Podgoretsky ©   (22.09.07 14:36) [40]
> > oxffff  (22.09.2007 14:32:39)  [39]
>
> Может из-за var
> В этом случае да, параметры не идентичны.


Так является ли это упущением с вашей точки зрения?

Ведь именно по этой причине FreeAndNil имеет вид

procedure FreeAndNil(var Obj);

а не

procedure FreeAndNil(var Obj:Tobject);

Почему если типы совместимы, ссылки на них не совместимы?

Повторю еще раз

Так является ли это упущением с вашей точки зрения?


 
Anatoly Podgoretsky ©   (2007-09-22 14:50) [42]

> oxffff  (22.09.2007 14:44:41)  [41]

Мне как то все равно до FreeAndNil я ее не использую.


 
oxffff ©   (2007-09-22 14:54) [43]

Еще из этого разряда. Почему компилятор не пропускает

procedure abc(p:ppointer);
begin
end;

procedure TForm1.Button1Click(Sender: TObject);
var a:^Tobject;
begin
abc(a);
end;

Incompatible types: "TObject" and "Pointer"

IMHO.
Компилятор слегка подстроить для нормальной обработки этой ситуации.
А именно, если типы совместимы, то и ссылки и указатели на них должны совместимы
IMHO.


 
Anatoly Podgoretsky ©   (2007-09-22 14:57) [44]

> oxffff  (22.09.2007 14:54:43)  [43]

Ну так и говорит - типы не совместимые.


 
oxffff ©   (2007-09-22 15:00) [45]


> Anatoly Podgoretsky ©   (22.09.07 14:57) [44]
> > oxffff  (22.09.2007 14:54:43)  [43]
>
> Ну так и говорит - типы не совместимые.


Ну а почему вы можете присвоить Tobject к pointer. И наоборот.

Почему?


 
Leonid Troyanovsky ©   (2007-09-22 15:00) [46]


> oxffff ©   (22.09.07 14:54) [43]

> Еще из этого разряда. Почему компилятор не пропускает

Конечно, достаточно уйти от var и никаких ограничений,
за исключением необходимости добавлять @.

type
 PObject = ^TObject;
 TMyObject = class
   x: TObject;
 end;

procedure abc(a: PObject);
begin
 ShowMessage(a^.ClassName);
 a^ := nil;
end;

procedure TForm1.Button1Click(Sender: TObject);
var a:tMyobject;
begin
a:= TMyobject.Create;
a.x := TObject.Create;
abc(@a.x);
Caption :=  Format("%p", [Pointer(a.x)]);
end;


Только, подобная "гибкость" только плодит проблемы.

--
Regards, LVT.


 
oxffff ©   (2007-09-22 15:02) [47]

Если следовать логике компилятора.

Он должен не пропустить. Однако вы знаете он пропустит.

procedure abc(p:pointer);
begin
end;

procedure TForm1.Button1Click(Sender: TObject);
var a:Tobject;
begin
abc(a);
end;


 
oxffff ©   (2007-09-22 15:07) [48]


> Только, подобная "гибкость" только плодит проблемы.


В чем проблема в вашем примере?


 
Leonid Troyanovsky ©   (2007-09-22 15:13) [49]


> oxffff ©   (22.09.07 15:02) [47]

> Он должен не пропустить. Однако вы знаете он пропустит.

Ограничение относится только к var параметрам,
Types of actual and formal var parameters must be identical (E2033)

For a variable parameter, the actual argument must be of the exact type of the formal parameter.

Почитай статью.

Не пойму в чем смущение ума :)

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2007-09-22 15:16) [50]


> oxffff ©   (22.09.07 15:07) [48]

> В чем проблема в вашем примере?

В моем их нет, но в подобных - отсутствие возможности контролировать типы, т.е. та самая совместимость TObject - pointer.

--
Regards, LVT.


 
oxffff ©   (2007-09-22 15:19) [51]


> Types of actual and formal var parameters must be identical
> (E2033)



> exact type


Да но к каким потенциальным граблям могут, если мы попросим их расширить эту функциональность. Вопрос в этом.

Вернемся к простому примеру с Tconrol и Tobject.

procedure abc(var a:Tobject);
begin
end;

procedure TForm1.Button1Click(Sender: TObject);
var a:tControl;
begin
abc(a);
end;

Почему бы не пропускать данный вызов. Ведь Tobject является подмножеством tControl и поэтому совместим.

Почему авторы ограничили именно до  exact type?


 
oxffff ©   (2007-09-22 15:22) [52]


> Leonid Troyanovsky ©   (22.09.07 15:16) [50]
>
> > oxffff ©   (22.09.07 15:07) [48]
>
> > В чем проблема в вашем примере?
>
> В моем их нет, но в подобных - отсутствие возможности контролировать
> типы, т.е. та самая совместимость TObject - pointer.


Но тем не менее проблем будет имхо не больше, чем когда вы пишите так

procedure TForm1.Button1Click(Sender: TObject);
var a:pointer;
begin
a:=self;
end;


 
Ping   (2007-09-22 15:28) [53]

Почему бы не пропускать данный вызов. Ведь Tobject является подмножеством tControl и поэтому совместим.

procedure Test(var Obj: TObject);
begin
 Obj := TBitmap.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Obj: TWinControl;
begin
 Test(Obj);
end;


Вот поэтому...


 
oxffff ©   (2007-09-22 15:34) [54]


> Вот поэтому...


Но Imho это решаемо.
Захочешь ограничить. Сделаешь так

procedure Test(var Obj: TControl);
begin
Obj := TBitmap.Create;
end;


 
Ping   (2007-09-22 15:37) [55]

Захочешь ограничить. Сделаешь так

Как это относится к FreeAndNil()?


 
oxffff ©   (2007-09-22 15:41) [56]


> Как это относится к FreeAndNil()?


oxffff ©   (22.09.07 14:44) [41]


 
Leonid Troyanovsky ©   (2007-09-22 15:46) [57]


> oxffff ©   (22.09.07 15:22) [52]

> Но тем не менее проблем будет имхо не больше, чем когда
> вы пишите так

Ну, это, скорее, вынужденые локальные меры.
Информация о типе, видимо, сохраняется "в уме" пишущего.
А от глобальных процедур требуют большего.
Т.е., чтобы случайно не передать туда не то.

--
Regards, LVT.


 
Ping   (2007-09-22 15:52) [58]

В частном случае, для FreeAndNil(), когда производится только обниление переменной - такое решение, возможно, и подошло бы.

Но

При передаче параметров по ссылке (var), при предлагаемом тобой подходе, можно вернуть все, что душе угодно (в пределах наследования). Компилятор  - он не телепат. Есть формальная логика. И если для Паскаля постулируется сильная типизация, то компилятор, при передаче по ссылке, будет требовать, чтобы передаваемая ссылка была на объект требуемого типа. Не нравится - пиши на С.

P.S. "Я дерусь... потому что я... дерусь!" (С) ?


 
oxffff ©   (2007-09-22 15:59) [59]


>  И если для Паскаля постулируется сильная типизация, то
> компилятор, при передаче по ссылке, будет требовать, чтобы
> передаваемая ссылка была на объект требуемого типа.


Сильная типизация?
А как насчет в совместимости pointer и Tobject?
Далее как насчет дочерних типов?

>P.S. "Я дерусь... потому что я... дерусь!" (С) ?

Я хочу сделать свою жизнь проще. :)


 
Anatoly Podgoretsky ©   (2007-09-22 16:18) [60]

> oxffff  (22.09.2007 15:59:59)  [59]

Pointer и pPointer разные вещи, вторая уже строгая типизация


 
oxffff ©   (2007-09-22 16:29) [61]


> Anatoly Podgoretsky ©   (22.09.07 16:18) [60]
> > oxffff  (22.09.2007 15:59:59)  [59]
>
> Pointer и pPointer разные вещи, вторая уже строгая типизация


А почему язык со строгой типазацией закрывает глаза на первую?
И причину такого поведения не подскажите?

Почему бы не сделать свой выбор в пользу неявного приведения для ссылочных типов с простой семантикой копирования.
А именно для типов Tobject, нетипизированного указателя и указателей на типы с простой семантикой копирования? А как же для ссылок на эти типы.


 
Anatoly Podgoretsky ©   (2007-09-22 16:34) [62]

То что это документировано, или передаешь var Name без типа или var Name: тип, тогда должно быть соответствие формальных и фактических параметров.


 
Anatoly Podgoretsky ©   (2007-09-22 16:35) [63]

А насчет хотелок, многие хотели бы превратить Паскаль в Си или Бейсик и обидно, что Борланд иногда идет на поводу.


 
oxffff ©   (2007-09-22 16:39) [64]


> Anatoly Podgoretsky ©   (22.09.07 16:34) [62]
> То что это документировано, или передаешь var Name без типа
> или var Name: тип, тогда должно быть соответствие формальных
> и фактических параметров.


Да об этом и речи нет.

Я о расширении языка.
И чтобы не было каламбура по типу oxffff ©   (22.09.07 14:54) [43].

Только скажите как в языке со строгой типизацией присутствуют конструкции untyped var, out, const педачи параметров?


 
Anatoly Podgoretsky ©   (2007-09-22 16:41) [65]

> oxffff  (22.09.2007 16:39:04)  [64]

К Вирту, он папа и к извращенцам из Борланда.


 
oxffff ©   (2007-09-22 16:45) [66]


> Anatoly Podgoretsky ©   (22.09.07 16:35) [63]
> А насчет хотелок, многие хотели бы превратить Паскаль в
> Си или Бейсик и обидно, что Борланд иногда идет на поводу.
>


Я все таки думую нужно быть не гордым, а расчетливым и "видеть" как одни конструкции удобнее, или быстрее других. Согласитесь, что конструкция for in действительна удобна. Хоть я и пишу до сих пор на 7 версии.Но считаю ее удобной. Также как и внесение статических методов в record.
Также как и nested types, class var. И даже те же Class helpers и record helper.
Не смотря на что приходится писать и на других языках включая С++,C#, ASM и ряд других.
Все равно Delphi мне ближе.


 
oxffff ©   (2007-09-22 16:50) [67]


> Но считаю ее удобной.


Я о новых конструкциях.

Сейчас я поехал в баню париться. :)
Вечером приеду и с вашего позволения я был бы рад продолжить дисскусию.
Спасибо всем за диалог.


 
Leonid Troyanovsky ©   (2007-09-22 16:55) [68]


> oxffff ©   (22.09.07 16:29) [61]

> Почему бы не сделать свой выбор в пользу неявного приведения
> для ссылочных типов с простой семантикой копирования.
> А именно для типов Tobject, нетипизированного указателя
> и указателей на типы с простой семантикой копирования? А
> как же для ссылок на эти типы.

А зачем?
Передача var TObject - извращение, FreeAndNil тому иллюстрация.

Все, что нужно потомку TObject должно быть в _его_ методах,
а не в глобальных регулярных процедурах.

--
Regards, LVT.


 
oxffff ©   (2007-09-24 10:09) [69]


> Все, что нужно потомку TObject должно быть в _его_ методах,
>
> а не в глобальных регулярных процедурах.


Согласитесь, что переменная типа  Tobject является лишь ссылкой на объект. А методы "должны" выполнять операции связанные с объектом, а не со ссылкой на него. Поэтому технически невозможно "грамотно" обнулить ссылку на объект, по причине того, что self передается by value.
А передовать ссылку на объект by ref в метод объекта не "грамотно".
Конечно можно создать невиртуальный классовый метод в Tobject, который принимает ссылку на объект и делает то, что делает FreeAndNil.
Но фактически классовый метод является регулярной функцией с ограниченным scope и дополнительным параметром на VMT, что избыточно по причине того, что VMT является ненужным параметром, и его мы может при желании изъвлечь из объекта.

Таким образом из-за ref семантики объектов в delphi операции над ссылкой и вынесли за пределы object scope. Поэтому это не извращение.

Вопрос, а как вы бы постулили в C++, где object is value type semantic?


 
Kolan ©   (2007-09-24 10:11) [70]

> конструкция for in действительна удобна. Хоть я и пишу до
> сих пор на 7 версии.Но считаю ее удобной.

Вот потому и считаешь, а я получал internal error из-за неё. Поэтому не использую&#133


 
oxffff ©   (2007-09-24 10:20) [71]


> Kolan ©   (24.09.07 10:11) [70]
> > конструкция for in действительна удобна. Хоть я и пишу
> до
> > сих пор на 7 версии.Но считаю ее удобной.
>
> Вот потому и считаешь, а я получал internal error из-за
> неё. Поэтому не использую…


oxffff ©   (22.09.07 16:50) [67]

Более того я выявил баг в реализации for in и отправил на qc, который получил уже open статус

Но тем не менее cчитаю ее удобной.


 
Kolan ©   (2007-09-24 10:30) [72]

> Но тем не менее cчитаю ее удобной.

Если бы переменную не заводить, то былобы хорошо совсем&#133


 
Turbouser ©   (2007-09-24 10:40) [73]

> [16] Anatoly Podgoretsky ©   (21.09.07 20:23)

Посмеялся :)) Спасибо за порцию позитива :)))


 
Leonid Troyanovsky ©   (2007-09-24 11:29) [74]


> oxffff ©   (24.09.07 10:09) [69]

> Согласитесь, что переменная типа  Tobject является лишь
> ссылкой на объект. А методы "должны" выполнять операции
> связанные с объектом, а не со ссылкой на него. Поэтому технически
> невозможно "грамотно" обнулить ссылку на объект, по причине
> того, что self передается by value.

Ссылка на объект отличается от самого объекта (тоже ссылки)
лишь (лишним) разыменованием. By-reference vs by-value - тоже.

Ну, а раз оно лишнее, то это и есть изврат :)

Да и, во-ще, тема, IMHO, себя исчерпала,
а FreeAndNil - MD.

--
Regards, LVT.


 
Плохиш ©   (2007-09-24 11:53) [75]

"Каждому овощу своё время"...


 
oxffff ©   (2007-09-24 11:55) [76]


> Leonid Troyanovsky ©   (24.09.07 11:29) [74]
>
> > oxffff ©   (24.09.07 10:09) [69]
>
> > Согласитесь, что переменная типа  Tobject является лишь
>
> > ссылкой на объект. А методы "должны" выполнять операции
>
> > связанные с объектом, а не со ссылкой на него. Поэтому
> технически
> > невозможно "грамотно" обнулить ссылку на объект, по причине
>
> > того, что self передается by value.
>
> Ссылка на объект отличается от самого объекта (тоже ссылки)
> лишь (лишним) разыменованием. By-reference vs by-value -
>  тоже.
>
> Ну, а раз оно лишнее, то это и есть изврат :)
>
> Да и, во-ще, тема, IMHO, себя исчерпала,
> а FreeAndNil - MD.
>
> --
> Regards, LVT.


Я думаю мы с вами говорим о разных вещах.


 
oxffff ©   (2007-09-24 12:12) [77]


> Ссылка на объект отличается от самого объекта (тоже ссылки)
> лишь (лишним) разыменованием. By-reference vs by-value -
>  тоже.


Методы связаны с блоком памяти в куче, а не с самой ссылкой на этот блок.
Поэтому обнуление ссылки является грамотным вынесением в регулярную процедуру.

А вы как предлагаете?

procedure Tobject.FreeAndNil(var obj:Tobject);?
или class procedure Tobject.FreeAndNil(var obj:Tobject); ?


 
Anatoly Podgoretsky ©   (2007-09-24 12:26) [78]

> oxffff  (24.09.2007 12:12:17)  [77]

Tobject.Free;
Tobject := nil;

И не будет таких фокусов, как

FreeAndNil(Integer)


 
oxffff ©   (2007-09-24 12:59) [79]


> FreeAndNil(Integer)


freeandnil(integer);
freeandnil(5);

Такое даже не откомпилируется. ;)

Тогда уж типизировать параметр.


 
Игорь Шевченко ©   (2007-09-24 13:04) [80]

Borland же честно подписал "Be careful to only pass TObjects to this routine." :)


 
Anatoly Podgoretsky ©   (2007-09-24 13:04) [81]

Откомпилируется, не в таком конец виде, это же шаблон

var
  I: Integer;
begin
  I := 0;
  FreeAndNil(I);


 
Anatoly Podgoretsky ©   (2007-09-24 13:14) [82]

> Игорь Шевченко  (24.09.2007 13:04:20)  [80]

В гробу такую честность.


 
Инс ©   (2007-09-24 13:24) [83]


> Функция FreeAndNil сравни функии IncDay

IncDay - хорошая функция. Позволяет не привязываться к реализации типа TDateTime, а заодно делает код более читаемым, особенно если в нем интенсивно используются подобные IncXXX-функции.


 
Turbouser ©   (2007-09-24 13:30) [84]

> [83] Инс ©   (24.09.07 13:24)
> IncDay — хорошая функция.

=))) Был тут энтузиаст :)
Свой  incday изобрел — у EGA23 до сих пор наверное
на стене висит — бо настроение поднимать :)))


 
Leonid Troyanovsky ©   (2007-09-24 13:32) [85]


> oxffff ©   (24.09.07 12:12) [77]

Согласен с Анатолием.

Хорошо б еще не забывать,
что ссылка может быть не единственной.

--
Regards, LVT.


 
Anatoly Podgoretsky ©   (2007-09-24 13:56) [86]

> Leonid Troyanovsky  (24.09.2007 13:32:25)  [85]

Правильно не надо закладываться на повторное использование переменных.
Просто надо решать надо иначе, через защищенное поле и контролируемое свойство и волосы будут шелковистыми.
Это решение дешевле, чем искать проблемы, героически с ними бороться.
А основная претензия к функции, что параметр не типизированый, со всем вытекающим из этого.


 
oxffff ©   (2007-09-24 14:41) [87]


> А основная претензия к функции, что параметр не типизированый,
>  со всем вытекающим из этого.


Так сделали они это по известным причинам, на которые вы намекали выше.
А именно, чтобы использовать в качестве параметра, любой ссылочный тип в основном Tobject и pointer. Но поскольку они не совместимы, если их передавать как var.

Им достаточно было сделать то, что я предлагаю, а именно сделать неявное приведение для ccылочных типов с простой семантикой копирования переданных как var параметр. И было бы счастье и удобство.


 
Инс ©   (2007-09-24 14:46) [88]


> Anatoly Podgoretsky ©   (24.09.07 13:04) [81]

Что, неужели вы в своих проектах так и делали?


 
Anatoly Podgoretsky ©   (2007-09-24 14:58) [89]

> oxffff  (24.09.2007 14:41:27)  [87]

Ну причины мы разобрали, а вот претензии остались.
Правда никто и не заставляет это использовать.
Счастье то будет в количестве строк и дополнительном геморое. Вот если они сделают это на уровне языка, тогда другое дело, только нафиг оно нужно. Пусть программист несет ответственность за свои действия.


 
Anatoly Podgoretsky ©   (2007-09-24 15:00) [90]


> Что, неужели вы в своих проектах так и делали?

Конечно нет, это же демонстрация. Да и как бы я мог это сделать, если я не использую FreeAndNil


 
Leonid Troyanovsky ©   (2007-09-24 15:02) [91]


> Anatoly Podgoretsky ©   (24.09.07 13:56) [86]

> Просто надо решать надо иначе, через защищенное поле и контролируемое
> свойство

Я даже предлагал как-то пример подобного

http://groups.google.com/group/fido7.ru.delphi.chainik/msg/2af895b1f348cbd1?dmode=source&output=gplain

--
Regards, LVT.


 
oxffff ©   (2007-09-24 15:03) [92]


> Вот если они сделают это на уровне языка, тогда другое дело,
>  только нафиг оно нужно


Так я именно об этом. :)


 
Инс ©   (2007-09-24 15:06) [93]


> Конечно нет, это же демонстрация. Да и как бы я мог это
> сделать, если я не использую FreeAndNil

Насколько я понял, вы не используете именно потому, что боитесь так сделать. Странная у вас позиция, ну не нравится вам, и не пользуйтесь. Какой тут геморой может быть, кроме того надуманного, что вы привели, я не знаю. Раз уж такое дело, то и Dispose использовать вредно. Там ведь параметр типа Pointer стоит, который на самом деле таковым быть не должен.


 
Anatoly Podgoretsky ©   (2007-09-24 15:08) [94]

> Leonid Troyanovsky  (24.09.2007 15:02:31)  [91]

Так это решение вполне квалифицированое, в рамках идеологии ООП Дельфи.


 
Anatoly Podgoretsky ©   (2007-09-24 15:09) [95]

> oxffff  (24.09.2007 15:03:32)  [92]

Ты об нафиг оно нужно


 
Anatoly Podgoretsky ©   (2007-09-24 15:16) [96]

> Инс  (24.09.2007 15:06:33)  [93]

Не боюсь, я уже давно ничего не боюсь. Выбор сделан с осознанием.
Таки и не использую.
А кто сказал, что я Dispose использую?


 
oxffff ©   (2007-09-24 15:17) [97]


> Anatoly Podgoretsky ©   (24.09.07 15:09) [95]
> > oxffff  (24.09.2007 15:03:32)  [92]
>
> Ты об нафиг оно нужно


:)

Вот если они сделают это на уровне языка


 
Инс ©   (2007-09-24 15:22) [98]


> А кто сказал, что я Dispose использую?

А где, говоря о Dispose, я сказал "Вы"?


 
Anatoly Podgoretsky ©   (2007-09-24 15:23) [99]

В контексте сообщения отнес к себе, а оказалось я тут не причем.


 
Инс ©   (2007-09-24 15:30) [100]

А интерфейсами лучше вообще никогда не пользоваться, там в одном из ключевых методов (QueryInterface) вообще out-параметр.


 
Плохиш ©   (2007-09-24 15:31) [101]


> Раз уж такое дело, то и Dispose использовать вредно.

Борланды в справке всё подробненько расписали, но "не царское это дело читать справку" у ССЗБ-н...


 
Инс ©   (2007-09-24 15:32) [102]


> Борланды в справке всё подробненько расписали, но "не царское
> это дело читать справку" у ССЗБ-н...

Это ты не мне, а [82] объясни.


 
Anatoly Podgoretsky ©   (2007-09-24 15:38) [103]

Чего тут спорить, с момента появления FreeAndNil ломают копья.
Разве это недостаточный критерий порочности?


 
Инс ©   (2007-09-24 15:41) [104]


> Чего тут спорить, с момента появления FreeAndNil ломают
> копья.

А до этого не ломали? Примеры поломаных об FreeAndNil копий в студию. Только не нужно приводить примеры, когда пострадавшие - уже упомянутые выше ССЗБ, они и на ровном месте себе шею сломают.


 
Джо ©   (2007-09-24 15:51) [105]

> [93] Инс ©   (24.09.07 15:06)
> Раз уж такое дело, то и Dispose использовать вредно. Там ведь  
> параметр типа Pointer стоит, который на самом деле таковым быть не
> должен.

Как это «не должен» и почему так?


 
Anatoly Podgoretsky ©   (2007-09-24 15:56) [106]

> Инс  (24.09.2007 15:41:44)  [104]

> Примеры поломаных об FreeAndNil копий в студию.

Так выброшены, и копья ломают не из-за пострадавших, они действительно ССЗБ
Ломают над нужностью/не нужностью, из-за названия, из-за политики Борланда, которые во многих случаях пошли по популисткому пути, после Д5.
Я на стороне тех, кто не согласен с Борландом.


 
Anatoly Podgoretsky ©   (2007-09-24 15:59) [107]

> Джо  (24.09.2007 15:51:45)  [105]

Не знаю, давно не использовал Dispose, но по моему должен, это же указатель на структуру или простой тип, а тут речь об объектах.
Разные все таки вещи. Я всегда использую GetMem/FreeMem может крома младенческих лет. Эти функции честные - сказано выделить память и никаких других толкований.


 
Инс ©   (2007-09-24 15:59) [108]


> Джо ©   (24.09.07 15:51) [105]

Мда...

type
 PMyRec = ^TMyRec;
 TMyRec = record
   s: String;
   i: Integer;
 end;

....

var
 rec: PMyRec;
 p: Pointer;
begin
 New(rec);
 rec^.s:="123";
 p:=rec;
 Dispose(p);
end;

Ловим утечку памяти из-за того, что память под строку освобождена не будет. А если сделать Dispose(rec) - все будет нормально.


 
Инс ©   (2007-09-24 16:04) [109]

GetMem/FreeMem - это тупое выделение и освобождение памяти. New и Dispose - умнее, они инициализируют и финализируют поля финализируемых типов. Если вызвать Dispose и передать ей нетипизированный указатель на стуктуру, содержащую такие поля, они финализированы не будут. Это очень частая ошибка.


 
oxffff ©   (2007-09-24 16:16) [110]


> Инс ©   (24.09.07 16:04) [109]
> GetMem/FreeMem - это тупое выделение и освобождение памяти.
>  New и Dispose - умнее, они инициализируют и финализируют
> поля финализируемых типов. Если вызвать Dispose и передать
> ей нетипизированный указатель на стуктуру, содержащую такие
> поля, они финализированы не будут. Это очень частая ошибка.
>


Тебе же сказали, что все делают ручками.

FreeMem(pointer(integer(rec^.s)-8))

Typeinfo это вред.

:)


 
oxffff ©   (2007-09-24 16:26) [111]


> Тебе же сказали, что все делают ручками.


А при возможности вообще пишут не на ассемблере, а сразу в машинных кодах.


 
Anatoly Podgoretsky ©   (2007-09-24 16:35) [112]

> Инс  (24.09.2007 16:04:49)  [109]

Я хорошо знаю, что они умнее и для чего нужны, но что же мне делать, если я не использую таких структур, да и память уже не помню когда выделял.


 
Anatoly Podgoretsky ©   (2007-09-24 16:36) [113]

> oxffff  (24.09.2007 16:26:51)  [111]

Не в ту степь обсуждение пошло, давайте продолжать обсасывать, облизывать FreeAndNil или исписались?


 
oxffff ©   (2007-09-24 16:38) [114]


> Anatoly Podgoretsky ©   (24.09.07 16:36) [113]
> > oxffff  (24.09.2007 16:26:51)  [111]
>
> Не в ту степь обсуждение пошло, давайте продолжать обсасывать,
>  облизывать FreeAndNil или исписались?


oxffff ©   (24.09.07 15:17) [97]


 
Инс ©   (2007-09-24 16:44) [115]


> Я хорошо знаю, что они умнее и для чего нужны, но что же
> мне делать, если я не использую таких структур, да и память
> уже не помню когда выделял.

Это я г-ну Джо объяснял, почему в парметрах к процедуре Dispose должен быть не Pointer, а типизированный указатель, хотя и вам тоже полезно будет, так как то, что вы хорошо знаете, что они умнее и для чего нужны - я уже сомневаюсь, судя по фразе "Не знаю, давно не использовал Dispose, но по моему должен". А насчет FreeAndNil - что тут обсуждать. Все уже давно сказано, каждый остается при своем. Я вот только понять не могу, почему те, кто не согласен с Borland, до сих пор сидят за Delphi...


 
Anatoly Podgoretsky ©   (2007-09-24 16:51) [116]

> Инс  (24.09.2007 16:44:55)  [115]

Это я сейчас не знаю (не помню), но это не относится к тому моменту, когда я захочу использовать.


 
Джо ©   (2007-09-24 17:12) [117]

> [115] Инс ©   (24.09.07 16:44)
> Это я г-ну Джо объяснял, почему в парметрах к процедуре
> Dispose должен быть не Pointer, а типизированный указатель

Увы, синтаксис не позволяет.


 
Инс ©   (2007-09-24 17:19) [118]


> Увы, синтаксис не позволяет.

Так и с FreeAndNil та же история. Нельзя написать
procedure FreeAndNil(var Obj: TObject);


 
Leonid Troyanovsky ©   (2007-09-24 17:35) [119]


> Джо ©   (24.09.07 17:12) [117]

> > Dispose должен быть не Pointer, а типизированный указатель
>
> Увы, синтаксис не позволяет.

А почему "увы"? По-моему, да и хрен с ним.
Кому сейчас нужны структуры со стрингами и вариантами.
Т.е., кому нужны - пользуют объекты.

--
Regards, LVT.


 
Джо ©   (2007-09-24 20:11) [120]

> [118] Инс ©   (24.09.07 17:19)
> Так и с FreeAndNil та же история. Нельзя написать
> procedure FreeAndNil(var Obj: TObject);

Да сколько угодно :)


> [119] Leonid Troyanovsky ©   (24.09.07 17:35)
>
> > Джо ©   (24.09.07 17:12) [117]
>
> > > Dispose должен быть не Pointer, а типизированный указатель
> >
> > Увы, синтаксис не позволяет.
>
> А почему "увы"? По-моему, да и хрен с ним.

Да по-моему так же.


 
oxffff ©   (2007-09-24 22:29) [121]

Leonid Troyanovsky ©   (24.09.07 17:35) [119]
Джо ©   (24.09.07 20:11) [120]

Конструктивно и выразительно, но непонятно.



Страницы: 1 2 3 4 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.10.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.8 MB
Время: 1.946 c
2-1190726454
R.O.O.T
2007-09-25 17:20
2007.10.21
Обработка исключений в TSocketConnection


6-1171820465
Alex Churton
2007-02-18 20:41
2007.10.21
Как создать интерфейс для удалёной железяки?


1-1186432049
abajun
2007-08-07 00:27
2007.10.21
Перетаскивание в TChart


2-1191060985
antonn
2007-09-29 14:16
2007.10.21
GetProcessAffinityMask


2-1190627006
misha_gr
2007-09-24 13:43
2007.10.21
TClientDataSet.Locate





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский