Lazarus

Free Pascal => General => Topic started by: simone on February 11, 2020, 12:27:47 am

Title: Class Reference Type Parameter With Default Value
Post by: simone on February 11, 2020, 12:27:47 am
I'm surely missing some basic thing… I apologize in advance… Let suppose we want to use a procedure with a class reference type parameter having a default value, as in the following example:

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode ObjFpc}
  3. type
  4.   C=class
  5.   end;
  6.  
  7.   C1=class(C)
  8.   end;
  9.  
  10.   C2=class(C1)
  11.   end;
  12.  
  13.   Cl = class of C;
  14.  
  15.   procedure Proc(aCl : Cl=C1); //<-- illegal expression
  16.   begin
  17.   end;
  18.  
  19. begin
  20. end.
  21.  

Why does the compiler says that there is an illegal expression in the definition of Proc? Thanks.
Title: Re: Class Reference Type Parameter With Default Value
Post by: PascalDragon on February 11, 2020, 09:23:47 am
You can't. Only those values that are also allowed for untyped constants (ordinals, floating point values, strings, sets) are allowed as default values.

You need to solve this using an overload:

Code: Pascal  [Select][+][-]
  1. procedure Proc(aCl: Cl);
  2. begin
  3. end;
  4.  
  5. procedure Proc; inline;
  6. begin
  7.   Proc(C1);
  8. end;

If you place the implementation of the overload without the parameter after the one with the parameter and the former has the inline modifier (like in the example above; for a unit you need to add the modifier to the declaration in the interface section) then you'll essentially have the same as only one call will be involved then.
Title: Re: Class Reference Type Parameter With Default Value
Post by: simone on February 11, 2020, 09:31:09 am
Thanks PascalDragon.  Waiting for the forum reply I had used this workaround (but without the intelligent use of the inline modifier).  I didn't know this limitation of parameters with default values.  Thanks for the explanation.
Title: Re: Class Reference Type Parameter With Default Value
Post by: simone on February 11, 2020, 01:40:20 pm
Only those values that are also allowed for untyped constants (ordinals, floating point values, strings, sets) are allowed as default values.

As a side note:  It's possible to set a class reference type parameter with NIL as default value:

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode ObjFpc}
  3. type
  4.   C=class
  5.   end;
  6.  
  7.   C1=class(C)
  8.   end;
  9.  
  10.   C2=class(C1)
  11.   end;
  12.  
  13.   Cl = class of C;
  14.  
  15.   procedure Proc(aCl : Cl=nil); //<-- OK
  16.   begin
  17.   end;
  18.  
  19. begin
  20. end.
Title: Re: Class Reference Type Parameter With Default Value
Post by: jamie on February 11, 2020, 10:40:32 pm
Your first attempt failed because you tried to change the type to another type, even if it is the same. You can only define a default value not a default type..

C1 here is a type not a variable.

The second attempted work because NIL is a value not a type which equals a zero pointer.
Title: Re: Class Reference Type Parameter With Default Value
Post by: simone on February 12, 2020, 12:28:10 am
Thanks Jamie. Indeed the concept of class reference in Object Pascal is similar, but different, respect to the notion of metaclass (i.e. class whose instances are classes) available in other OOP languages. I was misled by this analogy...
Title: Re: Class Reference Type Parameter With Default Value
Post by: PascalDragon on February 12, 2020, 09:24:58 am
Your first attempt failed because you tried to change the type to another type, even if it is the same. You can only define a default value not a default type..

C1 here is a type not a variable.

The second attempted work because NIL is a value not a type which equals a zero pointer.

Nonsense. For class types a class type is a valid value:

Code: Pascal  [Select][+][-]
  1. type
  2.   TMyObject = class
  3.   end;
  4.  
  5.   TMyClass = class of TMyObject;
  6.  
  7.   TMySubObject = class(TMyObject);
  8.  
  9. var
  10.   MyClass: TMyClass = TMySubObject;

This is one of the outstanding features of Object Pascal.

It's only that default parameters have further restrictions that simone's code does not work.
Title: Re: Class Reference Type Parameter With Default Value
Post by: jamie on February 12, 2020, 10:49:08 pm
Of course you can do that but he was doing it within the parameter case call.

different state all together..
Title: Re: Class Reference Type Parameter With Default Value
Post by: PascalDragon on February 13, 2020, 09:23:47 am
That's what I already said: that default parameters have further restrictions. But what you wrote was more general:

You can only define a default value not a default type..

To someone skimming over the posts it might not be clear that you're talking strictly about default parameters, thus my clarification.
TinyPortal © 2005-2018