gpt4 book ai didi

freepascal - 是否有一个过程可以在运行时在单个过程中初始化可变数量的对象?

转载 作者:行者123 更新时间:2023-12-02 23:27:45 27 4
gpt4 key购买 nike

我通常在程序开始时初始化一些变量,例如 TStringList 类型,然后释放它们。单独初始化感觉很尴尬,例如

listOne := TStringList.Create;
listTwo := TStringList.Create;
listTree := TString.Create;
{ etc, etc}

我更喜欢这样的过程,最后用另一个 for Free 来结束它们:

CreateStrings(listOne, listTwo, listThree);
CreateStrings([listOne, listTwo, listTree]); //using an array

是否有一个过程可以对可变数量的对象执行类似的操作?

如果不能对任意对象类型执行此操作,至少对相似类型或具有相同 Create 签名的类型如此?

最佳答案

我能想到的最好的办法是:

PROCEDURE CreateObjects(ClassType : TClass ; VAR O1); OVERLOAD;
BEGIN
TObject(O1):=NIL;
TObject(O1):=ClassType.Create
END;

PROCEDURE CreateObjects(ClassType : TClass ; VAR O1,O2); OVERLOAD;
BEGIN
TObject(O1):=NIL; TObject(O2):=NIL;
TObject(O1):=ClassType.Create; TObject(O2):=ClassType.Create
END;

PROCEDURE CreateObjects(ClassType : TClass ; VAR O1,O2,O3); OVERLOAD;
BEGIN
TObject(O1):=NIL; TObject(O2):=NIL; TObject(O3):=NIL;
TObject(O1):=ClassType.Create; TObject(O2):=ClassType.Create; TObject(O3):=ClassType.Create
END;

PROCEDURE FreeObjects(CONST Objects : ARRAY OF TObject);
VAR
O : TObject;
E : Exception;
ADR : POINTER;

BEGIN
E:=NIL;
FOR O IN Objects DO TRY
O.Free
EXCEPT
ON X:Exception DO BEGIN
E:=X; ADR:=ExceptAddr
END
END;
IF Assigned(E) THEN RAISE E AT ADR
END;

PROCEDURE TMainForm.FormCreate(Sender : TObject);
VAR
SL1,SL2 : TStrings;

BEGIN
CreateObjects(TStringList,SL1,SL2);
FreeObjects([SL1,SL2])
END;

您需要为要同时创建的每个对象创建一个重载过程。同一 CreateObjects 调用中的所有对象都将创建为相同类型(您将作为第一个参数提供),并且只能使用该类型的无参数构造函数来创建。

在构造之前进行 NIL 赋值的原因是为了确保传入的变量始终具有有效值(NIL 或指向请求类型的类)。这也意味着与普通代码相比:

O:=TObject.Create;
TRY
// Blah, Blah
FINALLY
O.Free
END;

你应该使用

TRY
CreateObjects(TObject,O1,O2);
// Blah, Blah
FINALLY
FreeObjects([O1,O2])
END;

即。将对象的创建移至 TRY/FINALLY block 内。

如果你是 FreeAndNIL 的支持者,那么你可以这样做:

PROCEDURE FreeAndNilObjects(VAR O1,O2); OVERLOAD;
BEGIN
TRY
FreeAndNIL(O1)
FINALLY
FreeAndNIL(O2)
END
END;

PROCEDURE FreeAndNilObjects(VAR O1,O2,O3); OVERLOAD;
BEGIN
TRY
FreeAndNIL(O1)
FINALLY
TRY
FreeAndNIL(O2)
FINALLY
FreeAndNIL(O3)
END
END
END;

这个有点奇怪的构造确保在所有传入的对象上调用 FreeAndNIL,但也意味着如果发生任何异常,它将是您将收到的最后一个引发的异常,并且任何先前的异常都将被丢失的。然而,它确实确保所有对象都被(尝试)释放。

编辑:更新了 FreeObjects 以正确处理任何对象的 .Free 调用中可能发生的任何异常。与 FreeAndNilObjects 过程一样,它将处理除最后一个异常之外的任何异常,并在确保至少尝试在每个传入对象上调用 .Free 后重新引发此异常。

关于freepascal - 是否有一个过程可以在运行时在单个过程中初始化可变数量的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20660146/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com