2011-02-26 208 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

相關問題