c++ - 类实例和指针背后的 Delphi 设计原则是什么?

标签 c++ class delphi pointers

我有 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使用类和指针的问题。

  1. 如果使用 o := MyObject.Create 创建对象使用 Delphi 中的堆分配,您如何在堆栈上分配对象?
  2. 如果声明为o: MyObject 的特定类型类的变量确实是一个指针,那么为什么从未使用过^ 指针符号。这是 Delphi 中的“便利”习语吗?
  3. 如何获取位于堆上的实际 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 通常只在堆上分配内存,那么:

  1. 将一个对象分配给另一个对象是否意味着它们都指向同一个地址?
  2. 为什么作业(“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/

相关文章:

delphi - TForm.ManualDock 应该调用 onFormShow 吗?

c++ - 如何传递数组对象?

c++ - 在 C++ 中使用指针按引用传递数组

c++ - 为什么 delete 可以在指向 const 的指针上执行而 free 不能?

delphi - 如何安全关闭H2219提示?

delphi - Delphi 动态数组包含哪些簿记数据?

c++ - 如何从派生类通过基类 ptr 访问 protected 基类函数

python - 除非我重置内核,否则 Jupyter Notebook 中的对象不是 "resetting"

css - 将父 ID 添加到大 css 文件中

Python 覆盖字符串 __hash__