Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.01;
Скачать: [xml.tar.bz2];




Вниз

Базовый вопрос: корректно ли в дестракторе нилить указатель на объект? 


Aleksandr   (2002-03-19 12:38) [0]

Суть проблемы такова: необходимо, чтобы указатель на объект при уничтожении становился nil (потому что Assigned только на это и может проверить). Допустимо ли делать так:

destructor MyThread.Destroy;
begin
DoSomething;
Inherited;
Self:=nil
end;



Виктор Щербаков   (2002-03-19 12:42) [1]

А толку то. Self - локальная переменная.



Aleksandr   (2002-03-19 13:00) [2]

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

procedure TForm1.FormDestroy;
begin
Inherited Destroy
Form1:=nil
end;

А это корректно?



DieHard   (2002-03-19 13:08) [3]

это в событии OnDestroy?
хм..



Polevi   (2002-03-19 13:18) [4]

корректно



kull   (2002-03-19 13:21) [5]

Да это в принципе коректно.
Это же не Self, внешняя - скорее всего даже глобальная переменная.
А Self:=nil это даже опасно, потому что дальше при выходе из Destroy может случится Acsecc Violation.

Ведь на сколько я помню Free вызывает Destroy...



Anatoly Podgoretsky   (2002-03-19 21:13) [6]

Aleksandr © (19.03.02 13:00)

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



kull   (2002-03-20 01:15) [7]

Народ! Может я что-то не понимаю? Но присваивать Self:=nil это нехорошо. Self - внутренняя переменная класса и желательно только читать из нее. А FreeAndNil, насколько я помню, сначала уничтожает объект, а потом присваевает переменной, которая хранила его nil. Это далеко не одно и тоже.



Ray   (2002-03-20 09:01) [8]

Вообщето не совсем понял. Ты хочеш внитри самого себя "обнилить"? Это каким же образом? Боюсь что тогда ты из процедуры не выйдеш, вернее выйдеш но куда попаде не знаю .
Хотя не уверен, почемуто сколько лет пишу но такой надобьности никогда небыло. Может пересмотриш реалитзацию другой части проекта, где у тебя нужна вот это проверки на nil.?



Digitman   (2002-03-20 10:02) [9]

>Aleksandr
Если возникла такая необходимость, присваивай nil тем объектным переменным, которые хранят указатель на тек.объект (именно - объектным переменным, а не Self).

К примеру :

TMyClass = class(..)
..
public
constructor Create(..);
destructor Destroy; override;
end;

var
Ref1_To_MyObject : TMyClass;
Ref2_To_MyObject : TMyClass;

...

destructor TMyClass.Destroy;
begin
...
inherited;
Ref1_To_MyObject := nil;
Ref2_To_MyObject := nil; // (*)
end;

...

Ref1_To_MyObject := TMyClass.Create(..); //указатель на экз-р
Ref2_To_MyObject := Ref1_To_MyObject; // копия указателя

Ref1_To_MyObject.Free;
Ref2_To_MyObject.Free; // не вызовет исключения из-за (*)




PGM   (2002-03-20 10:21) [10]

Я предпочитаю для тех же целей (проверка Assigned) использовать Free всегда в связке
Form1.Free;
Form1 := nil;



Виктор Щербаков   (2002-03-20 10:48) [11]

PGM (20.03.02 10:21)
Тогда уж FreeAndNil(Form1);



Rooman   (2002-03-20 20:02) [12]

Ответ на вопрос: некорректно, т.к. не достигает предполагаемой вами цели. Более того, компилятор просто выкидывает строчку self:=nil (Value assigned to "Self" never used), т.е. просто ее не компилирует. Связано это с тем, что self - локальная переменная.



D. Lex   (2002-03-21 16:15) [13]

В общем случае эта задача не решается, по этому поводу дебаты уж много лет как отшумели. Одно из правил ООП: метод объекта не может изменять сам объект, он может изменять только его содержимое. Обнуление указателя на объект - это, фактически, изменение объекта. Применительно к дельфе, единственный корректный способ - это использование FreeAndNil(), или
Object1.Free;
Object1 := nil;
, что, в общем-то, одно и то же.



Виктор Щербаков   (2002-03-21 16:24) [14]


> Обнуление указателя на объект - это, фактически, изменение
> объекта.

Указатель - это переменная, содержащая адрес объекта. Как же изменяя значение этой переменной (хотя бы обнуляя её) мы сможем изменить сам объект?



Digitman   (2002-03-21 16:28) [15]

>Виктор Щербаков
Имелся ввиду, наверное, Self как внутрисистемный указатель на тек.экз-р класса, метод которого обращается к этому Self с попыткой обнуления.




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.01;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.74 MB
Время: 0.022 c
3-56              Turalyon              2002-03-05 13:35  2002.04.01  
Триггер в IB6


3-69              Huliganka             2002-03-06 21:27  2002.04.01  
Delphi & MS SQL server


3-77              Dimedrol              2002-02-13 10:32  2002.04.01  
начинаю с Interbase.


1-169             KB                    2002-03-19 13:45  2002.04.01  
StringGrid


1-232             cok                   2002-03-20 18:36  2002.04.01  
Tray