我有 C++ 背景,对类、指针和内存地址相当了解。但是,对于 Delphi,我发现自己很困惑。
我知道,当您在函数/过程的 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
的特定类型类的变量确实是一个指针,那么为什么从未使用过^
指针符号。这是 Delphi 中的“便利”习语吗? 如何获取位于堆上的实际
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 的基本原理,但我还没有找到任何人(无论是物理上还是在 Internet 上)可以对上述内容进行令人满意的解释。
编辑
鉴于 Delphi 通常只在堆上分配内存,那么:
- 将一个对象分配给另一个对象是否意味着它们都指向同一个地址?
为什么作业(“THIS ASSIGNMENT”)无法编译?
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)]));
关于c++ - 类实例和指针背后的 Delphi 设计原则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21975960/