我需要在此实例中获取指向我的类实例的指针。我不能直接使用“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”是指向此类实例的指针吗?如何将此指针用于此对象之外的未来使用?如何从这个值中获取正确的指针?
答案 0 :(得分:12)
您正在尝试比较三个完全不同的实体。
@test返回变量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 :(得分: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;