情况
我要写一个类,构造函数是一个自定义的,因为我需要初始化一些值.这是迄今为止写的代码:
type TCombinatorio = class(TObject) private valN,valK: integer; result: double; public property K: integer read valK; property N: integer read valN; constructor Create(valN: integer; valK: integer); end; constructor TCombinatorio.Create(valN: Integer; valK: Integer); begin inherited Create; Self.valN := valN; Self.valK := valK; if ((valN < 0) or (valK < 0)) then begin raise Exception.Create('N and K must be >= 0'); end; end;
由于我要做一些数学计算,我需要避免负数.
题
我可以以这种方式在构造函数中调用异常吗?我以这种方式运行代码:
procedure TForm1.Button1Click(Sender: TObject); var a: TCombinatorio; b: string; begin a := TCombinatorio.Create(5,-2); try //some code finally a.Free; end; end;
如你所见,我的构造函数有错误的参数,因为第二个是负数.我也不能理解(根据我的构造函数的代码)如果finally中的a.Free是真正需要的,因为当构造函数引发异常时,析构函数被调用.
我想包括a:= TCombinatorio.Create(5,-2);里面的try-finally块,以避免这个问题,但我不确定.你怎么看?
解决方法
你的代码是绝对正确的.提高构造函数的异常是非常可观的.你知道析构函数被调用.
你问这个代码:
a := TCombinatorio.Create(5,-2); try //some code finally a.Free; end;
你担心在对象已经被销毁之后,将会调用自由.这不可能发生.如果在构造函数中引发异常,那么它会向上传播调用堆栈.这在try块开始之前发生,所以finally块不执行.的确,对a的任务不会发生.
在尝试中移动创作将是灾难性的,实际上是一个非常常见的错误.假设你这样做:
// WARNING THIS CODE IS DEFECTIVE try a := TCombinatorio.Create(5,-2); //some code finally a.Free; end;
现在如果一个异常被提出,然后Free被调用,但在什么?变量a未初始化.即使是这样,它还不是双倍的.