Paer Toernell
asked on
Delphi Copy a Var integer to another var integer
I have quite normal parameter like:
Procedure Something(var test:integer);
In the form i have a global variabel (well global to that form) defied as:
public
{ Public declarations }
var gtest :integer;
Now i want to transfer the pointer from test to gtest.
gtest :=test; wont work. How should it be done?
Procedure Something(var test:integer);
In the form i have a global variabel (well global to that form) defied as:
public
{ Public declarations }
var gtest :integer;
Now i want to transfer the pointer from test to gtest.
gtest :=test; wont work. How should it be done?
ASKER
If we have a variable, say
myInt : integer;
Now I pass that to a procedure:
MyProcedure (myInt);
Defined as:
Procedure MyProcedure (var MyVarInt :integer);
Begin
MyVarInt :=35;
End
Now i can change MyVarInt and myInt will change. Fine, normal, standard. No problem.
But if i want to copy the functionality of MyVarInt to another "var name:integer" how do i do that?
myInt : integer;
Now I pass that to a procedure:
MyProcedure (myInt);
Defined as:
Procedure MyProcedure (var MyVarInt :integer);
Begin
MyVarInt :=35;
End
Now i can change MyVarInt and myInt will change. Fine, normal, standard. No problem.
But if i want to copy the functionality of MyVarInt to another "var name:integer" how do i do that?
Put a form and a button... Define two global variables... Copy my code:
var
Form1: TForm1;
A, B : integer;
implementation
{$R *.dfm}
Procedure MyProcedureA (var MyVarInt :integer);
Begin
MyVarInt :=35;
End;
Procedure MyProcedureB (MyVarInt :integer);
Begin
MyVarInt :=35;
End;
procedure TForm1.Button1Click(Sender : TObject);
begin
A := 10;
ShowMessage('Variable before enter the procedure A = '+ inttostr(A));
MyProcedureA(A);
ShowMessage('Variable after enter the procedure A = '+ inttostr(A));
B := 20;
ShowMessage('Variable before enter the procedure B = '+ inttostr(B));
MyProcedureB(B);
ShowMessage('Variable after enter the procedure B = '+ inttostr(B));
end;
Run the program, you will see:
Variable A = 10 before MyProcedureA
Variable A changes to 35
Variable A = 35 as soon MyProcedureA ends.
Variable B =20 before MyProcedureB
Variable B changes to 35 inside the procedure
Variable B = 20 as soon MyProcedureB ends.
Notice MyProcedureA has a formal parameter: (var MyVarInt : integer);
MyVarInt is not the name of a variable, is the formal name of a variable you´re going to pass thru the procedure. Var means that it can change when the procedure finish. This is why A starts with a 10 and finish with 35. If you dont use the var word, MyProcedureB will use the formal parameter MyVarInt to pass value to the procedure, but when the procedure finish, the variable B will return to the original value. This is why B = 20 and finish with B =20.
In fact, you dont have to create a MyVarInt variable. I repeat, this is just the formal name indicating that you´re going to pass a variable to the procedure.
For example, if you want B equals whatever A has after MyProcedureA, you can write:
A=10;
MyProcedureA(A);
B := A;
Please check in any Pascal manual the use of the var parameter in a procedure. Check passing a variable by reference or by value. I think this is what you´re not understanding.
Regards
Lopem
var
Form1: TForm1;
A, B : integer;
implementation
{$R *.dfm}
Procedure MyProcedureA (var MyVarInt :integer);
Begin
MyVarInt :=35;
End;
Procedure MyProcedureB (MyVarInt :integer);
Begin
MyVarInt :=35;
End;
procedure TForm1.Button1Click(Sender
begin
A := 10;
ShowMessage('Variable before enter the procedure A = '+ inttostr(A));
MyProcedureA(A);
ShowMessage('Variable after enter the procedure A = '+ inttostr(A));
B := 20;
ShowMessage('Variable before enter the procedure B = '+ inttostr(B));
MyProcedureB(B);
ShowMessage('Variable after enter the procedure B = '+ inttostr(B));
end;
Run the program, you will see:
Variable A = 10 before MyProcedureA
Variable A changes to 35
Variable A = 35 as soon MyProcedureA ends.
Variable B =20 before MyProcedureB
Variable B changes to 35 inside the procedure
Variable B = 20 as soon MyProcedureB ends.
Notice MyProcedureA has a formal parameter: (var MyVarInt : integer);
MyVarInt is not the name of a variable, is the formal name of a variable you´re going to pass thru the procedure. Var means that it can change when the procedure finish. This is why A starts with a 10 and finish with 35. If you dont use the var word, MyProcedureB will use the formal parameter MyVarInt to pass value to the procedure, but when the procedure finish, the variable B will return to the original value. This is why B = 20 and finish with B =20.
In fact, you dont have to create a MyVarInt variable. I repeat, this is just the formal name indicating that you´re going to pass a variable to the procedure.
For example, if you want B equals whatever A has after MyProcedureA, you can write:
A=10;
MyProcedureA(A);
B := A;
Please check in any Pascal manual the use of the var parameter in a procedure. Check passing a variable by reference or by value. I think this is what you´re not understanding.
Regards
Lopem
there is no functionality in an integer type
it just holds a number, that's the only functionality it has
if you want to add functionality, you need to look at OOP: Object Oriented Programming
and define your own type, with the functionality you want
for instance: an integer, with a status indicator of overloaded:
for this sample, i used a TPersistent descendant, in which you need to override the Assign procedure
This allows copying properties from 1 object to another:
and if you want multiple variables to have the same value
then either, only use 1 variable
or use an observer pattern to indicate changes to listening objects
http://www.nickhodges.com/post/Delphi-and-the-Observer-Pattern.aspx
it just holds a number, that's the only functionality it has
if you want to add functionality, you need to look at OOP: Object Oriented Programming
and define your own type, with the functionality you want
for instance: an integer, with a status indicator of overloaded:
type
TMyStatus = class(TPersistent)
private
fValue: integer;
protected
function GetOverLoaded: Boolean;
public
constructor Create(aValue: Integer = 0); virtual;
procedure Assign(Source: TPersistent); override;
property Value: Integer read fValue write fValue;
property OverLoaded: Boolean read GetOverLoaded;
end;
constructor TMyStatus.Create(aValue: Integer = 0);
begin
inherited Create;
fValue := aValue;
end;
function TMyStatus.GetOverLoaded: Boolean;
begin
Result := fStatus > 100;
end;
procedure TMyStatus.Assign(Source: TPersistent);
begin
if Source is TMyStatus then
begin
fValue := TMyStatus(Source).Value;
end else
inherited Assign(Source);
end;
for this sample, i used a TPersistent descendant, in which you need to override the Assign procedure
This allows copying properties from 1 object to another:
var
MyStatus1, MyStatus2: TMyStatus;
begin
MyStatus1 := TMyStatus.Create(20);
MyStatus2 := TMyStatus.Create;
MyStatus2.Assign(MyStatus1);
...
and if you want multiple variables to have the same value
then either, only use 1 variable
or use an observer pattern to indicate changes to listening objects
http://www.nickhodges.com/post/Delphi-and-the-Observer-Pattern.aspx
If you call
MyProcedure(gtest);
...value of outer variable gtest will be changed - because you define procedure that way...
MyProcedure(gtest);
...value of outer variable gtest will be changed - because you define procedure that way...
ASKER
Ok, let me rephrase my question. How do i copy a variable that don't hold a value but hold a reference to another variable so that variable also hold the same reference. I can do it with pointers or i can do i t with an object but that's not what i want.
So we have some forms that have an integer. Another object needs the reference to that integer. The form is not given, it variate and so can the name of the variable. To pass the reference into the the object is easy:
To receive the reference is easy:
BUT the variable that holds the rererence (aRef ) will only work locally inside the procedure PassReference and vanish when PassReference goes out of scope . I need it to be available as long as the object exists.
Thats why i have a "global" variable defined in the object.
So i need something like:
So how do i copy/transfer the reference from aRef to gMyRef ?
So we have some forms that have an integer. Another object needs the reference to that integer. The form is not given, it variate and so can the name of the variable. To pass the reference into the the object is easy:
SomForm:
myobject.PassReference (MyInteger);
To receive the reference is easy:
procedure tmyobject.PassReference(var aRef : integer);
begin
end;
BUT the variable that holds the rererence (aRef ) will only work locally inside the procedure PassReference and vanish when PassReference goes out of scope . I need it to be available as long as the object exists.
Thats why i have a "global" variable defined in the object.
tmyobject= class(Tobject)
Public
Var gMyRef : Integer;
So i need something like:
procedure tmyobject.PassReference(var aRef : integer);
begin
gMyRef :=CopyReferenceOf(aRef );
end
So how do i copy/transfer the reference from aRef to gMyRef ?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Yes, works. Thanx
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
var
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
var gINtRef : pInteger;
gint : Integer;
Procedure SetRef(Var aint : integer);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender : TObject);
begin
SetRef(gint);
gINtRef^:=25;
Memo1.Lines.Add(IntToStr(g int));
end;
procedure TForm1.SetRef(var aint: integer);
begin
gINtRef:=@aint;
end;
end.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
var
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
var gINtRef : pInteger;
gint : Integer;
Procedure SetRef(Var aint : integer);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender
begin
SetRef(gint);
gINtRef^:=25;
Memo1.Lines.Add(IntToStr(g
end;
procedure TForm1.SetRef(var aint: integer);
begin
gINtRef:=@aint;
end;
end.
Procedure Something(var test:integer);
the variable "test" is the formal name of the variable. Because you defined it as "var", you're saying to the compiler that the variable is passing by reference and not value. That means that when you use the procedure in any part of your program, you have to make the call:
Something(gtest);
(assuming this is a global variable for this procedure)...
if in your procedure you do something like this: test := test + 5;
then gtest will be whatever value has originally + 5. And the result finally will be gtest + 5.
If you define your procedure like this:
Procedure Something(test:integer);
without the var parameter, your variable with pass by value, and when you exit the procedure, your variable (for instance gtest) will not change the value at all.
regards,
Lopem