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

Reply via email to