Based on the background of C ++, I understand the classes, pointers, and memory addresses well. However, with Delphi, I find myself confused.
I understand that when you declare a variable of a specific type of a class in the var section of a function / procedure, what you actually declare is the POINTER for this class. For example, the following Delphi and C ++ are roughly equivalent, both allocate the amount of memory needed for the MyObject class on the heap.
// Delphi procedure Blah.Something(); var o: MyObject; begin o := MyObject.Create; o.Free; end; // C++ void Blah::Something() { MyObject *o = new MyObject(); delete o; }
In C ++, using pointers (and references) allows you to use virtual methods for a class hierarchy. However, if you do not have a class hierarchy, you can declare a variable on the stack (which is faster). If you need to pass the variable around as a pointer, you can simply get its address using the & operator.
// C++ void Blah::Something() { // This is allocated on the stack. MyObject o; // This address of this stack-allocated object is being used. doSomethingWithAnOhPointer(&o); }
At this point, I have several questions regarding the use of classes and pointers in Delphi.
- If you use
o := MyObject.Create distribution in Delphi when creating an object with o := MyObject.Create , how do you allocate the object on the stack? - If a variable of a particular class type declared as
o: MyObject is really a pointer, then why the ^ character of the pointer was never used. Is this a "convenient" idiom in Delphi? How can you get the address of the actual MyObject on the heap? I tried: the following.
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.
I may have misunderstood some of the basics of Delphi, but I have not found anyone (physically or on the Internet) who can explain this above my satisfaction.
EDIT
Given that Delphi usually allocates memory on the heap, then:
- Does assigning one object to another mean that both of them point to the same address?
Why is the assignment ("THIS RECORDING") not compiled?
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 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;
(To give some context, there are several variables that must point to the same object, but can point to different objects, so I want to compare their location in memory to determine if this is so.)