2010-09-29 103 views
5

我需要在這個實例中獲取我的類實例的指針。我不能直接使用「Self」,我需要存儲指針以備將來使用。我想下面的代碼:德爾福自我指針的使用

type 
    TTest = class(TObject) 
    public 
     class function getClassPointer: Pointer; 
     function getSelfPointer: Pointer; 
    end; 

class function TTest.getClassPointer: Pointer; 
begin 
    Result := Pointer(Self); 
end; 

function TTest.getSelfPointer: Pointer; 
begin 
    Result := Pointer(Self); 
end; 

而且兩者的結果是錯誤的 - 這樣的代碼:

test := TTest.Create; 
Writeln('Actual object address: ', IntToHex(Integer(@test), 8)); 
Writeln('Class "Self" value: ', IntToHex(Integer(test.getClassPointer()), 8)); 
Writeln('Object "Self" value: ', IntToHex(Integer(test.getSelfPointer()), 8)); 

回報:

Actual object address: 00416E6C 
Class "Self" value:  0040E55C 
Object "Self" value:  01EE0D10 

請幫助我瞭解,這是什麼 「自我」 的價值? 「Self」是這個類實例的指針嗎?如何將此指針用於此對象之外的未來使用?如何從這個值得到正確的指針?

回答

12

你試圖比較三種完全不同的實體。

@test返回變量測試的地址,而不是它指向的對象實例。

test.getClassPointer()返回類元數據的地址,由編譯器生成的常量數據結構,運行時可以找到虛擬方法表,運行時類型信息表等等。一個類的所有實例共享相同的類元數據結構。類元數據的指針是對象實例的類型標識 - 對象如何知道它在運行時的類型。

test.getSelfPointer()爲您提供內存中對象實例的實際地址。兩個對象實例(單獨創建)將具有不同的實例地址。 test.getSelfPointer()將等於測試實例變量的內容:指針(測試)

例如(僞代碼,未測試):

type TTest = class 
    end; 

var test1: TTest; 
    test2: TTest; 

begin 
    test1 = TTest.Create; // allocates memory from the global heap, stores pointer 
    test2 = test1;   // copies the pointer to the object into test2 variable 
    writeln("Test1 variable points to: ", IntToHex(Integer(Pointer(test1)))); 
    writeln("Test2 variable points to: ", IntToHex(Integer(Pointer(test1)))); 
end. 
+1

謝謝!現在我明白如何使用它了!TTest(指針(測試))或TTest(test.getSelfPointer()) - 就是我需要的=) – soar 2010-09-29 17:50:31

+4

這些對於Delphi來說是非常奇怪的構造。你確定你不會讓自己變得過於複雜嗎?你的foo = TTest(指針(測試))與只是說foo = test相同。 Delphi中的每個對象實例變量實際上都是一個指針。指針只是在表面之下。 – dthorpe 2010-09-29 17:55:22

+1

此外,'getClassPointer'與內建的'ClassType'方法相同。 – 2010-09-29 18:03:24

0

在你的代碼片段test已經是參考的真實情況,所以你應該嘗試

Writeln('Actual object address: ', IntToHex(Integer(Pointer(test)), 8)); 

而且你可能不需要任何getSelfPointer方法。如果你想要第二個參照對象實例test已經引用,寫:

var 
    SecondReferenceToTest: TTest; 
SecondReferenceToTest := test; 

看到這一點,你可以試試:

type 
    TTest = class(TObject) 
    public 
    Name: string; 
    end; 

procedure TestProc; 
var 
    test, SecondReferenceToTest: TTest; 
begin 
    test := TTest.Create; 
    try 
    test.Name := 'Named via "test" reference'; 
    SecondReferenceToTest := test; 
    ShowMessage(SecondReferenceToTest.Name); 
    finally 
    test.Free; 
    end; 
end; 
+0

這樣 - 到對象外獲取參考,但我必須做什麼,以返回此對象的方法內的有效指針?就像我的樣本。 – soar 2010-09-29 17:43:49

+0

@Soara,如果你打算在對象上調用一個方法,那麼你*已經有*對象的引用。對象本身沒有任何「特殊」訪問權限。在一個實例方法中,「Self」是對象的引用,如果調用者在對象上調用方法,它必須具有相同的引用。在類方法中,「Self」是對類的引用,而不是類的任何實例。 – 2010-09-29 18:05:24

+0

我的問題 - 只是樣本,我真的使用結構,其中對象放在其他對象作爲領域,並沒有「測試」內。現在我可以傳遞給它正確的指針。謝謝大家 ! – soar 2010-09-29 18:13:53