Alan Colburn wrote:
> So if you're passing an object as a parameter you're passing a copy of the
> pointer, even if you don't use the added var keyword in the parameter list.
> If you're passing something like a string or integer, the var keyword -->
> passing a copy of a pointer, so there's ultimately two pointers pointing to
> the same memory address. Not including the var keyword when passing a string
> or integer --> a copy of the string or integer data and a new pointer
> pointing to the copied data's memory address.
>
> It's starting to make sense. Thank you!
>
When you're passing an object as a parameter you're passing a copy of a
pointer because an object is an pointer.
When you're passing an integer as a parameter you're passing a copy of
the integer.
When you're passing a string as a parameter the safest thing to do is
think of it as passing a copy of the string. This is in fact NOT true
because strings are also objects and that makes them pointers, but
Delphi's compiler hides this from us, making strings behave more like
integers then objects (this kind of magic is called copy-on-write if
you're interested).
When you're passing an "var" parameter, you're passing an pointer to a
variable that holds the original data. If the called procedure modifies
the parameter, it will in fact modify the original var.
When you're passing an object as an "var" parameter you're passing an
pointer to the variable that holds the pointer to the object. So in fact
an var object parameter is an pointer to a pointer, but it's easier to
think of it in terms of "pointer to the variable".
When you're passing an "var integer" you're again passing an pointer to
the original variable.
Same is true for string.
Ex (1):
procedure test_proc;
var i:Integer;
b:Byte;
begin
var_proc(7); // error - you need to pass a REAL variable to the var_proc
non_var_proc(7); // OK - the non_var_proc takes a value, not a variable
b := 8;
var_proc(b); // error - you need to pass a variable of the expected type.
// while b is a real variable, it's of type byte,
not integer, so
// it will not work
non_var_proc(b); // OK - non_var_proc takes a value, not a variable,
// so Delphi can convert the "byte" to an Integer
for the call
// (ther're both numbers)
var_proc(i); // OK: "i" is a real variable of the correct type
var_proc(i+1); // Error: "i+1" is an expression, not a variable. It
evaluates to
// a value of type integer, but it's not a integer
variable so it will
// not work for a var parameter
end;
procedure var_proc(var i:Integer);
begin
i := 7;
end;
procedure non_var_proc(i:Integer);
begin
ShowMessage(i);
end;
Ex (2):
procedure test_proc;
var SourceList:TStringList;
begin
var_proc(TStringList.Create); // Error! the var_proc expects a
variable of type TStringList.
// while the expresion
TStringList.Create does evaluate to a expresion
// of type "TStringList", it's not
a variable!
non_var_proc(TStringList.Create); // OK! non_var_proc takes an
TStringList param
// so this would work just fine
non_var_proc(SourceList); // OK! SourceList is a TStringList variable
so it's value can be passed
// to the non_var_proc procedure
end;
procedure var_proc(var X:TStringList);
begin
// ANY change to the X variable will affect the ORIGINAL SourceList
variable.
X := nil; // This will make the original SourceList variable "nil"
X := TStringList.Create; // This will initiate the original SourceList
variable
X.Add('Test'); // You can use X as any other TStringList variable
end;
procedure non_var_proc(X:TStringList);
begin
X.Add('Test2'); // You can use the X value as any other TStringList;
The added text
// will be found in the original SourceList
X.Free; // You can do that; Free is a method of the TStringList class
so you may call it.
// This will FREE the memory allocated for the
TStringList those making both
// X and SourceList point to no-longer-allocated memory.
(as they're both pointers
// pointing to the same memory area to start with).
X := TStringList; // This will set the value of "X" to a brand-new
TStringList object.
// X will no longer point to the same area as
SourceList!
X.Add('test'); // X is a usable variable.
// Uppon EXIT of this proc, the SourceList variable in test_proc will
point to JUNK!
// Doing ANYTHING to SourceList will likely generate an Access Violation.
// The only SAFE thing you can do to SourceList is something that acts
on the "pointer",
// not on the pointed-to-memory, like setting SourceList := nil or
SourceList := TStringList.Create.
end;
_______________________________________________
Delphi mailing list -> [email protected]
http://www.elists.org/mailman/listinfo/delphi