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

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

Как узнать, что созданный объект "свободен"?


AlexanderMS ©   (2007-01-17 17:55:00) 

Иными словами, как узнать, что экземпляр объекта "уже отработал" (вызван Create, затем Free) или вовсе не создавался.

Хотел поставить условие if Object1 <> nil, но nil он тогда, когда не был создан (как я понял), и после Free он остаётся не равен nil.
К примеру:
var
begin
 SL := TSomething.Create;
 // SL уже не nil
 SL.Free;
 // SL всё равно не nil
 
end;


Rial   (2007-01-18 12:07:00) [1]

> [11] Плохиш ©   (18.01.07 11:24)
> Спасибо, повеселил :-D
> Прочитай код, который Sergey Masloff в деструктор написал ;-)

Извините если кого обидел где то ...
Завтра экзамен, уже 30 часов не спал. :(
Все, больше пока нигде не пишу, дабы
не скомпрометировать себя.


Плохиш   (2007-01-18 11:24:00) [2]


> AlexanderMS ©   (17.01.07 17:55)  
> Иными словами, как узнать, что экземпляр объекта "уже отработал"
> (вызван Create, затем Free) или вовсе не создавался.

Это всё является обязанностью программиста использующего объект. Потому что никакой искусственный интеллект не может протелепатировать какая дикая идея возникла в воспалённом мозгу сумашедшего программиста. Поэтому предусмотренно, что при создании экземпляра объекта, конструктор вернёт ссылку на созданный экземпляр, а программист волен делать с ней всё, что его воспалённой душе угодно. Таким образом, эта Ваша переменнаяObject1 никакого отношения ни к каким экземплярам объекта не имеет и Выи, в общем случае, только Вы вольны записывать в неё всё что Вам будет угодно, хоть ссылку на экземпляр объекта, хоть nil, хоть номер дома, на котором сидить пятая ворона в третьем ряду на снимке со спутника штабквартиры нато...
Итак, ответом на Ваш вопрос будет то, что Вы сами должны следить за своим созданием, работой и уничтожением объектов.

> Rial ©   (18.01.07 09:45) [9]

Спасибо, повеселил :-D
Прочитай код, который Sergey Masloff в деструктор написал ;-)


ors_archangel   (2007-01-18 11:15:00) [3]


> Rial ©   (18.01.07 09:45) [9]

Ошибка где-то в другом месте? Вот же "ошибка":

> Raise Exception.Create('xxx'); // Если это убрать то все
> честно закрывается


Имхо, нужно сам деструктор написать, чтобы он старался как можно больше осводить ресурсов перед смертью:

destructor TMyObj.Destroy;
var
errs: array of string;
begin
try
  v := Unassigned;
except
  on e: Exception do AddErr(e.Message);
end;
inherited;
if errs <> nil then RaiseErrs(errs);
end;

И FreeAndNil в KOL правильнее написан - сначала обнуление, а потом уже работа, которая может вызвать ошибки - Free:

procedure Free_And_Nil( var Obj );
var Obj1: PObj;
begin
 Obj1 := PObj( Obj );
 Pointer( Obj ) := nil;
 Obj1.Free;
end;


Rial   (2007-01-18 09:45:00) [4]


>[8] Sergey Masloff   (18.01.07 00:01)
> var
> o : TMyObj;
> begin
> o := TMyObj.Create(self);
> o.Foo();
> FreeAndNil(o);
> // Исключение и Ексель остался висеть

Ошибка где - то в другом месте.
Возможно, это замечательное o.Foo() лезет куда - то
далеко, куда ему не положено. Либо кто то другой
портит объект. Вообщем, исключение возникает при
вызове o.Destroy; А от этого уже другие методы лечения.
Попробуй написать просто
o.Destroy;
Теоритически, должно также возникнуть исключение.
Либо, самый простой вариант, исключение вообще
возникает на предыдущей строке.


Sergey Masloff   (2007-01-18 00:01:00) [5]

вот например

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

 TMyObj = class(TComponent)
 private
   v : Variant;
 public
   constructor Create(AOwner : TComponent); reintroduce; override;
   destructor Destroy; reintroduce; override;
   procedure Foo();
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

uses ComObj;

{ TMyObj }

constructor TMyObj.Create(AOwner: TComponent);
begin
 inherited;
 v := CreateOleObject('Excel.Application');
end;

destructor TMyObj.Destroy;
begin
 Raise Exception.Create('xxx'); // Если это убрать то все честно закрывается
 v := Unassigned;
 inherited;
end;

procedure TMyObj.Foo;
begin
 v.Visible := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 o : TMyObj;
begin
 o := TMyObj.Create(self);
 o.Foo();
 FreeAndNil(o);
 // Исключение и Ексель остался висеть
end;

end.


oxffff   (2007-01-17 23:57:00) [6]

Поскольку объект не содержит презаголовок,
то вариант запросить у менеджера памяти информацию о распределение памяти по указателю.

Если память распределна, значит "Что-то есть".
Далее проверить, что в try except "Что это есть".


Sergey Masloff   (2007-01-17 23:50:00) [7]

Rial ©   (17.01.07 23:42) [5]
Почему пустой? Зачем пустой? Не пустой. Нормальный объект. В деструкторе освобождеется ряд ресурсов. При попытке освобождения первого из них получаем исключение (например).


Rial   (2007-01-17 23:42:00) [8]

> [3] Sergey Masloff   (17.01.07 23:26)
> Temp.Free;  ============> А если тут что поймаем? Obj мы
> уже поиксовали ;-))


procedure TObject.Free;
begin
 if Self <> nil then
   Destroy;
end;

Пустой указатель не страшен.
Так что все кошерно :)

А вообще то, мы же в Temp-е ссылку запомнили,
мы же не Obj.Free делаем.


Джо   (2007-01-17 23:29:00) [9]

> Temp.Free;  ============> А если тут что поймаем? Obj мы
> уже поиксовали ;-))

Ничего не поймаем.


Sergey Masloff   (2007-01-17 23:26:00) [10]


procedure FreeAndNil(var Obj);
var
 Temp: TObject;
begin
 Temp := TObject(Obj);
 Pointer(Obj) := nil;
 Temp.Free;  ============> А если тут что поймаем? Obj мы уже поиксовали ;-))
end;


Desdechado   (2007-01-17 19:01:00) [11]

или FreeAndNil


Rial   (2007-01-17 18:04:00) [12]

Вместо банального Free, используй
Object.Free;
Object:=Nil;
^)

procedure rmFree(Var Obj);
asm
//Начало
push ebx
mov ebx, eax
//Вызов метода
mov eax, [ebx]
call System.TObject.Free
//Зануление
xor eax, eax
mov [ebx], eax
//Конец
pop ebx
end;


Наверх

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