What is the difference between
TMyThread.Create(r);
and using the new keyword? Pascal classes are made in the heap, I suppose, so after .create(r) you get a reference, I think to the initiated object on the heap, correct?
Consider the following code:
type
TMyClass = class(TObject)
public
constructor Create;
end;
constructor TMyClass.Create;
begin
inherited Create;
end;
var
O: TMyClass;
begin
O := TMyClass.Create;
O := O.Create;
end.
The line 15 (constructor with the class at the front) is compiled as:
# [22] O := TMyClass.Create;
movl $1,%edx
movl $VMT_$P$UNIT1_$$_TMYCLASS,%eax
call P$UNIT1$_$TMYCLASS_$__$$_CREATE$$TMYCLASS
movl %eax,U_$P$UNIT1_$$_O
The edx is loaded with 1 and the eax with the VMT pointer. The thing is that when edx is preloaded with 1, then the generated
Create calls the
NewInstance entry from the given VMT, usually
TObject.NewInstance unless overriden. See lines 15,16:
P$PROGRAM$_$TMYCLASS_$__$$_CREATE$$TMYCLASS:
# [unit1.pas]
# [8] begin
pushl %ebp
movl %esp,%ebp
leal -12(%esp),%esp
pushl %ebx
pushl %esi
pushl %edi
# Var $vmt located at ebp-4, size=OS_32
# Var $self located at ebp-8, size=OS_32
# Var $vmt_afterconstruction_local located at ebp-12, size=OS_S32
movl %eax,-8(%ebp)
movl %edx,-4(%ebp)
cmpl $1,%edx
jne .Lj6
movl -8(%ebp),%eax
movl -8(%ebp),%edx
call *52(%edx) ;<---------------------- NewInstance into VMT
movl %eax,-8(%ebp)
.balign 4,0x90
.Lj6:
cmpl $0,-8(%ebp)
NewInstance allocates needed memory from heap via GetMem, calls InitInstance, then returns it into eax register (which is actually the Self).
At the other hand, if called with a variable instead of a class in the front (line 16):
movl %eax,U_$P$PROGRAM_$$_O
# [16] O := O.Create;
movl $-1,%edx
call P$PROGRAM$_$TMYCLASS_$__$$_CREATE$$TMYCLASS
movl %eax,U_$P$PROGRAM_$$_O
# [17] end.
Here the edx is preloaded with -1 (not 1) and the eax with the value of the variable O, i.e. the Self implicit argument. With the edx not equal to 1, the call to
NewInstance gets skipped, assuming eax is already pointing to the instance memory.
That way:
- You can call the constructor qualified with the class name, thus allocating a new memory chunk for the instance on the heap before the first line of the Create constructor gets executed, you may think the constructors are actually a class methods in that case
OR - You can preallocate memory by other means, assign the pointer to it to the variable, call InitInstance to set the VMT pointer, and then call the constructor as a regular method qualified by a variable name.
The former is the usual way the instances were created in Object Pascal, the latter (or variation of it) can be used if you want some special allocation scheme, say to reuse an instance once allocated and to skip FreeMem/GetMem pair.
But when do you use the new keyword? And can you use it in this specific case? In C++ the constructor is called when you initiate with the new keyword not with calling the constructor directly.
A bit confusing. 
The C++ objects are constructed implicitly and if you want them on the heap you must use the new/delete operators. In contrast the FPC objects are actually just references and if you want them constructed you must do that explicitly.
In FPC new/dispose aren't used for that purpose. They're remnants from the original Pascal and not very much used nowadays.