这会导致内存泄漏吗?

JBA*_*JBA 0 delphi oop memory-leaks

type
  TTest = class
    a: integer;
  end;
  TTest2 = class(TTest)
    b: integer;
  end;

  var c:TTest;

  begin
    c:=TTest2.Create();
    c.Free;
  end;
Run Code Online (Sandbox Code Playgroud)

vcl*_*per 8

不,它不会.

基类类型的变量可用于从其子类中实例化对象(它们是类型兼容的),但请注意,使用这样的变量,您将只能访问TTest成员,而不能访问TTest2成员.那意味着; 你可以访问"a",但不能访问"b".

此外,如果在TTest2.Creation执行期间遇到任何异常,Create将不会返回部分构建的对象.

但是,如果在TTest2.Create和c.Free调用之间有其他代码,则在这些代码中引发异常会导致内存泄漏; 因为C.Free可能无法执行.在这种情况下,您应该使用try-finally块.


Dav*_*nan 5

不,这里没有内存泄漏.构造函数仅在成功时才返回新资源.如果构造函数成功并且您无法调用,则只能泄漏Free.由于在构造函数和调用之间不执行任何操作Free,因此不会发生泄漏.

如果构造函数失败则:

  • 调用析构函数以释放任何资源.
  • 提出了一个例外.
  • 构造函数不会返回,因为异常会更改程序流.
  • c在您的示例中,不会发生对象变量的赋值.

请注意,您已接受的@vcldeveloper的答案在声明nil返回时是错误的.引发的构造函数不返回任何内容.

您应始终使用try/finally包装Create/Free对,如下所示:

obj := TMyClass.Create;
try
  obj.DoSomething;
finally
  obj.Free;
end;
Run Code Online (Sandbox Code Playgroud)

您只需在分配资源保护资源.所以你把它try放在作业之后.

如果您将try构造函数放在错误之前:

try
  obj := TMyClass.Create;
  obj.DoSomething;
finally
  obj.Free;
end;
Run Code Online (Sandbox Code Playgroud)

如果构造函数失败则obj不会被分配,然后在Free运行时(并且它将由于finally运行而运行!),它会在未初始化的变量上调用,从而导致未定义的行为.