【发布时间】:2014-04-21 20:06:23
【问题描述】:
我正在使用 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,它也会被释放?
【问题讨论】:
-
B从何而来?它是在哪里定义的?
-
这是假代码。请提供真实代码。
A := A.Create是错误的。该代码不会运行。你不提供任何类型,所以我们不知道什么是什么。您将B用作类型和变量。这不可能是正确的。FreeAndNil接收无类型的var参数。您很可能正在尝试将属性作为参数传递。这是不允许的。您可以直接使用Free。您的对象所有权处理完全被破坏了。你不能继续这种疯狂的所有权方法。你肯定漏了很多。启用内存泄漏检查。在异常处理程序中释放对象很奇怪。 -
*我不是要重新设计代码。" 它需要重新设计。
-
很好,要么有两个声明(
B和A.B)而且它们混淆了,要么这不是真正的代码。但是,是的,A := A.Create不起作用。 -
@DavidHeffernan 和 Jerry Dodge 我已经更新了代码。非常感谢
标签: delphi oop delphi-2010