Recent

Author Topic: Class Reference Type Parameter With Default Value  (Read 811 times)

simone

  • Sr. Member
  • ****
  • Posts: 351
Class Reference Type Parameter With Default Value
« 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.
« Last Edit: February 11, 2020, 01:20:51 am by simone »
Microsoft Windows 10 64 bit - Lazarus 2.0.6

PascalDragon

  • Hero Member
  • *****
  • Posts: 1941
  • Compiler Developer
Re: Class Reference Type Parameter With Default Value
« Reply #1 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.

simone

  • Sr. Member
  • ****
  • Posts: 351
Re: Class Reference Type Parameter With Default Value
« Reply #2 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.
Microsoft Windows 10 64 bit - Lazarus 2.0.6

simone

  • Sr. Member
  • ****
  • Posts: 351
Re: Class Reference Type Parameter With Default Value
« Reply #3 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.
Microsoft Windows 10 64 bit - Lazarus 2.0.6

jamie

  • Hero Member
  • *****
  • Posts: 3257
Re: Class Reference Type Parameter With Default Value
« Reply #4 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.
The only true wisdom is knowing you know nothing

simone

  • Sr. Member
  • ****
  • Posts: 351
Re: Class Reference Type Parameter With Default Value
« Reply #5 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...
Microsoft Windows 10 64 bit - Lazarus 2.0.6

PascalDragon

  • Hero Member
  • *****
  • Posts: 1941
  • Compiler Developer
Re: Class Reference Type Parameter With Default Value
« Reply #6 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.

jamie

  • Hero Member
  • *****
  • Posts: 3257
Re: Class Reference Type Parameter With Default Value
« Reply #7 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..
The only true wisdom is knowing you know nothing

PascalDragon

  • Hero Member
  • *****
  • Posts: 1941
  • Compiler Developer
Re: Class Reference Type Parameter With Default Value
« Reply #8 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