2011-02-26 129 views
0
type 
    TTest = class 
    a: integer; 
    end; 
    TTest2 = class(TTest) 
    b: integer; 
    end; 

    var c:TTest; 

    begin 
    c:=TTest2.Create(); 
    c.Free; 
    end; 

回答

8

不,它不会。

基类类型的变量可用于从其子类实例化对象(它们是类型兼容的),但请注意,使用这样的变量只能访问TTest成员,而不能访问TTest2成员。这意味着;您可以访问“a”,但不能访问“b”。另外,如果在TTest2.Creation执行过程中遇到任何异常,Create将不会返回部分构建的对象。但是,如果在TTest2.Create和c.Free调用之间有其他代码,则在这些代码中引发异常可能导致内存泄漏;因为C.Free可能不会执行。在这种情况下,你应该使用try-finally块。

+1

构造函数在失败时不返回零。在你的评估中,你认为这个特殊的代码块不会泄漏,但它不是一个非常有用的构造。 – 2011-02-26 21:00:16

+0

谢谢艾伦,删除那部分不会误导未来的读者。 – vcldeveloper 2011-02-26 22:38:00

5

不,这里没有内存泄漏。如果成功,构造函数只返回一个新资源。您只能在构造函数成功时发生泄漏,并且不能致电Free。由于您在构造函数和Free的调用之间什么都不做,所以不会出现泄漏。

如果构造失败,那么:

  • 调用析构函数释放任何资源。
  • 引发异常。
  • 构造函数不会返回,因为异常会更改程序流。
  • 您的示例中的对象变量c的赋值不会发生。

请注意,您接受的@vcldeveloper的答案在说明返回nil时不正确。没有任何东西从引发的构造函数中返回。

你应该总是包装使用try /终于如下创建/免费对:

obj := TMyClass.Create; 
try 
    obj.DoSomething; 
finally 
    obj.Free; 
end; 

你只需要保护资源一旦被分配。所以你在作业后放置try

如果这是一个错误的构造函数之前放置try

try 
    obj := TMyClass.Create; 
    obj.DoSomething; 
finally 
    obj.Free; 
end; 

如果构造失败,那么obj不分配,然后当Free运行(它将运行感谢终于来了!)它在未初始化的变量上调用,导致未定义的行为。

+0

说“构造函数失败”意味着“对象构造中的代码导致了异常”是否正确? – mjn 2011-02-26 12:08:20

+0

是的,这是正确的。构造函数要么成功要么提出。 – 2011-02-26 12:15:36

相关问题