Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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


Aleksandr ©   (2002-03-19 12:38:00) 

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

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


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

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


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


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

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


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

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


Rooman   (2002-03-20 20:02:00) [4]

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


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

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


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

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


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

>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; // не вызовет исключения из-за (*)



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

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


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

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


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

Aleksandr © (19.03.02 13:00)

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


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

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

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


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

корректно


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

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


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

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

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

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


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

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


Наверх

Титульная страница Поиск, карта сайта Написать письмо