我正在使用Delphi 2010并且有一个问题是重新释放对象。
假设我有类似下面的代码,如果发生异常,我想清除TProduct和TPart。
如何释放正确包含的对象TPart?
//Clases are defined like this
TProduct = class(TRemotable)
private
FName: String;
FAge: Integer;
FColor: String;
FPart: TPart;
published
property Name: String read FName write FName;
property Age: Integer read FAge write FAge;
property Color: String read FString write FString;
property Part: TPart read FPart write FPart;
end;
TPart = class(TRemotable)
private
FName: String;
FColor: String;
published
property Name: String read FName write FName;
property Color: String read FString write FString;
end;
//Then in a method, code will get info from database, create objects and fill them
function MyFunction: TProduct;
begin
Result:=nil;
query.Open;
Result:=TProduct.Create;
try
try
Result.Name:=query.FieldByName('NAME').AsString;
Result.Age:=query.FieldByName('AGE').AsInteger;
Result.Color:=query.FieldByName('COLOR').AsString;
...
if (Result.Color='Blue') then
begin
Result.Part:=Part.Create;
Result.Part.Name:='Bottle';
Result.Part.Color:='Green';
end;
except
on e: Exception do
begin
//If exception occurred, I want to make sure
//that both TProduct and TPart objects are freed properly
FreeAndNil(Result); //works fine
FreeAndNil(Result.Part); //<-- WON'T COMPILE - Get "Constant object cannot be passed as var parameter"
Part.Free; //<--COMPILES but isn't FreeAndNil better?
end;
end;
finally
query.Close;
end;
end;
我不是要重新设计代码,只是为了确保如果创建了TPart,它也会被释放?
答案 0 :(得分:5)
正确的方法是让A
获得B
的所有权,让A
的析构函数免费B
。这样,您的异常处理程序只会担心释放A
,如果它是在引发异常之前创建的,它将释放B
。
type
ClassA = class
public
B: ClassB;
destructor Destroy; override;
end;
destructor ClassA.Destroy;
begin
B.Free;
inherited;
end;
var
A: ClassA;
begin
...
A := ClassA.Create;
try
...
A.B := ClassB.Create;
...
except
on e: Exception do
begin
FreeAndNil(A); // or A.Free;
...
end;
end;
...
end;