我理解当你在函数/过程的var部分声明一个特定类型的类的变量时,你真正声明的是该类的指针.例如,以下Delphi和C大致相同,都分配了堆上MyObject类所需的内存量.
// Delphi procedure Blah.Something(); var o: MyObject; begin o := MyObject.Create; o.Free; end; // C++ void Blah::Something() { MyObject *o = new MyObject(); delete o; }
在C中,使用指针(和引用)允许对类层次结构使用虚方法.但是,如果您没有类层次结构,则可以在堆栈上声明一个变量(执行速度更快).如果你需要将变量作为指针传递,你可以简单地用&操作符.
// C++ void Blah::Something() { // This is allocated on the stack. MyObject o; // This address of this stack-allocated object is being used. doSomethingWithAnOhPointer(&o); }
在这个阶段,我有一些关于Delphi使用类和指针的问题.
>如果用o:= MyObject.Create创建一个对象在Delphi中使用堆分配,那么如何在堆栈上分配一个对象?
>如果声明为o:MyObject的特定类型的类的变量实际上是指针,那么为什么^指针符号从未使用过.这是德尔福的“便利”成语吗?
>如何获取堆上实际MyObject的地址?我试过了:以下.
WriteLogLine('Address of object: ' + Format('%p',[@o])); // This prints the address of the 'o' pointer. WriteLogLine('Address of object: ' + Format('%p',[o])); // This causes the program to crash.
我可能误解了一些Delphi基础知识,但我没有找到任何人(身体上或互联网上)可以解释上述内容让我满意.
编辑
鉴于Delphi通常只在堆上分配内存,那么:
>将一个对象分配给另一个对象是否意味着它们都指向同一个地址?
>为什么作业(“这个作业”)没有编译?
procedure Blah.Something(); var o1: MyObject; o2: MyObject; oP: ^MyObject; begin o1 := MyObject.Create; o2 := o1; // Both variables "o1" and "o2" point to the same object on the heap. WriteLogLine(Format('@o1 = %p,@o2 = %p',[@o1,%o2])); // This SHOULD produce two different address,as it's the address of the "implied pointer". oP := o1; // THIS ASSIGNMENT will NOT compile. WriteLogLine(Format('oP = %p',[oP] o1.Free; o1 := nil; // The single object has been deleted,but o1 = nil while o2 <> nil end;
(为了给出一些上下文,有多个变量应该指向同一个对象但可能指向不同的对象,所以我想比较它们的内存位置以确定是否是这种情况.)
解决方法
If creating an object with o := MyObject.Create uses heap-allocation in Delphi,how do you allocate an object on the stack?
Delphi不允许在堆栈上分配类实例.它们总是在堆上分配.
If a variable of a specific type of class declared as o : MyObject is really a pointer,then why is the ^ pointer symbol never used. Is this a “convenience” idiom in Delphi?
是.
How can you get the address of the actual MyObject located on the heap?
试试这个:
WriteLogLine('Address of object: ' + Format('%p',[Pointer(o)]));