various ways of passing a class instance as a parameter

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

various ways of passing a class instance as a parameter

Graeme Geldenhuys-2
Hi,

What exactly is the difference (if any) between the parameter modifier
when you pass a class instance to a procedure?

In the example below, I can define foo() as follows...

procedure foo(AClass: TStringList);
  or
procedure foo(var AClass: TStringList);
  or
procedure foo(const AClass: TStringList);


...and the program output is always the same. As in the first case
where I don't specify var or const, how does FPC treat the AClass
parameter?


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
program a;

{$mode objfpc}{$H+}

uses
 Classes;

procedure foo(AClass: TStringList);
begin
  AClass.Add('inside foo');
end;

var
 sl: TStringList;
begin
  sl := TStringList.Create;
  try
    sl.Add('inside main');
    foo(sl);
    sl.Add('the end');
    writeln(sl.Text);
  finally
    sl.free;
  end;
end.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-


Here is the program output:

$ ./a
inside main
inside foo
the end



--
Regards,
  - Graeme -


_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://fpgui.sourceforge.net
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: various ways of passing a class instance as a parameter

Alexander Shishkin
15.11.2011 13:33, Graeme Geldenhuys пишет:
> Hi,
>
> What exactly is the difference (if any) between the parameter modifier
> when you pass a class instance to a procedure?
>

I your example there is no difference, except that "var" could be ~0.01%
slower

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: various ways of passing a class instance as a parameter

michael.vancanneyt
In reply to this post by Graeme Geldenhuys-2


On Tue, 15 Nov 2011, Graeme Geldenhuys wrote:

> Hi,
>
> What exactly is the difference (if any) between the parameter modifier
> when you pass a class instance to a procedure?

It behaves exactly the same as if you would pass a typed pointer.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: various ways of passing a class instance as a parameter

Martin Schreiber-2
In reply to this post by Graeme Geldenhuys-2

On Tuesday 15 November 2011 10.33:13 Graeme Geldenhuys wrote:

> Hi,

>

> What exactly is the difference (if any) between the parameter modifier

> when you pass a class instance to a procedure?

>

> In the example below, I can define foo() as follows...

>

> procedure foo(AClass: TStringList);

> or


Take a copy of the AClass instance pointer.


> procedure foo(var AClass: TStringList);


Take the address of the instance variable. The instance pointer can be changed by the procedure, so the type of the instance variable must match TStringList exactly otherwise the procedure could store a wrong class into the instance variable. Example:


procedure foo(var AClass: TList);

begin

aclass.free;

aclass:= Tlist.create;

end;

[...]

var

cl1: TStringList.

begin

foo(cl1); //does not compile

//now there would be a TList in a TstringList variable


> or

> procedure foo(const AClass: TStringList);

>

Take a copy of the AClass instance pointer, AClass is readonly.


> or

> procedure foo(constref AClass: TStringList);


Take the address of the instance variable, AClass is readonly.


Martin


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: various ways of passing a class instance as a parameter

Graeme Geldenhuys-2
On 15/11/2011, Martin Schreiber <mse00000@g.....> wrote:
>

Thanks Martin. Extending my example by changing the body of foo() too...

  AClass.Free;
  AClass := TStringList.Create;
  AClass.Add('inside foo');

...reveals a bit more about the differences.



>> procedure foo(const AClass: TStringList);
>>
> Take a copy of the AClass instance pointer, AClass is readonly.


This one confused me a bit. I thought the whole object would be
read-only, but in fact it is just the AClass instance pointer which
cannot be modified. The properties of AClass are still read-write.


--
Regards,
  - Graeme -


_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://fpgui.sourceforge.net
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: various ways of passing a class instance as a parameter

Martin Schreiber-2

On Tuesday 15 November 2011 11.00:34 Graeme Geldenhuys wrote:


> >> procedure foo(const AClass: TStringList);

> >

> > Take a copy of the AClass instance pointer, AClass is readonly.

>

> This one confused me a bit. I thought the whole object would be

> read-only, but in fact it is just the AClass instance pointer which

> cannot be modified. The properties of AClass are still read-write.


The wording was bad. Should be:

"

> procedure foo(AClass: TStringList);

> or


Take a copy of the AClass instance pointer.


> procedure foo(var AClass: TStringList);


Take the address of the instance variable. The instance pointer pointed by the address can be changed by the procedure, so the type of the instance variable must match TStringList exactly otherwise the procedure could store a wrong class into the instance variable. Example:


procedure foo(var AClass: TList);

begin

aclass.free;

aclass:= Tlist.create;

end;

[...]

var

cl1: TStringList.

begin

foo(cl1); //does not compile

//now there would be a TList in a TstringList variable


> or

> procedure foo(const AClass: TStringList);

>

Take a copy of the AClass instance pointer, AClass instance pointer is readonly.


> or

> procedure foo(constref AClass: TStringList);


Take the address of the instance variable, AClass instance pointer pointed by the address is readonly.

"

Martin


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: various ways of passing a class instance as a parameter

Alexander Shishkin
In reply to this post by Graeme Geldenhuys-2
15.11.2011 14:00, Graeme Geldenhuys пишет:

>
> This one confused me a bit. I thought the whole object would be
> read-only, but in fact it is just the AClass instance pointer which
> cannot be modified. The properties of AClass are still read-write.
>
>

Perhaps it will be good to add support for const method modifier as in
C++ and then make const class-instance parameters immutable.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal