Discussion:
[fpc-pascal] non-virtual class methods called from virtual regular method
LacaK via fpc-pascal
2021-04-29 06:51:47 UTC
Permalink
Hi *,

consider the following example

T1 = class
  class procedure CP1;
  procedure P1; virtual;
end;

T2 = class(T1)
  class procedure CP1;
end;

procedure T1.P1;
begin
  CP1; // here is called allways T1.CP1, right?
  // if I want call T2.CP1 then class procedure CP1 must be also
virtual, right?
  // so Self.CP1 does not take runtime type but is staticaly resolved
at compile time to T1.CP1 ?
end;

var
  c1: T1;

begin
  c1:=T2.Create;
  c1.P1; // here is called T2.P1 - runtime class type
end.

Thanks

Btw If I need for various class descendants define various class
constants, it is possible only by using class functions (getters), where
descendant class getter hides parents getter?

-Laco.

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.o
Michael Van Canneyt via fpc-pascal
2021-04-29 07:26:30 UTC
Permalink
Post by LacaK via fpc-pascal
Hi *,
consider the following example
T1 = class
  class procedure CP1;
  procedure P1; virtual;
end;
T2 = class(T1)
  class procedure CP1;
end;
procedure T1.P1;
begin
  CP1; // here is called allways T1.CP1, right?
  // if I want call T2.CP1 then class procedure CP1 must be also
virtual, right?
Yes
Post by LacaK via fpc-pascal
  // so Self.CP1 does not take runtime type but is staticaly resolved
at compile time to T1.CP1 ?
Yes.
Post by LacaK via fpc-pascal
end;
var
  c1: T1;
begin
  c1:=T2.Create;
  c1.P1; // here is called T2.P1 - runtime class type
end.
Thanks
Btw If I need for various class descendants define various class
constants, it is possible only by using class functions (getters), where
descendant class getter hides parents getter?
If they depend on the class, they're not "constants" to begin with, so a
getter function is the right approach. For such purposes I use virtual class
functions.

Michael.
LacaK via fpc-pascal
2021-04-29 11:04:41 UTC
Permalink
Post by Michael Van Canneyt via fpc-pascal
Post by LacaK via fpc-pascal
Hi *,
consider the following example
T1 = class
  class procedure CP1;
  procedure P1; virtual;
end;
T2 = class(T1)
  class procedure CP1;
end;
procedure T1.P1;
begin
  CP1; // here is called allways T1.CP1, right?
  // if I want call T2.CP1 then class procedure CP1 must be also
virtual, right?
Yes
Post by LacaK via fpc-pascal
  // so Self.CP1 does not take runtime type but is staticaly resolved
at compile time to T1.CP1 ?
Yes.
This is bit counter-intuitive for me:

In regular virtual method, I expect, that Self resolves to runtime class
type, thust calling CP1 should resolve to runtime type class method.

But from compiler POV I understand, that symbol CP1 must be somehow
resolved at compile time, so compiler looks at CP1 method definition
(and if not virtual then resolves to class method of type where is used).

In principle *virtual* class methods as such are for me strange ;-)
Post by Michael Van Canneyt via fpc-pascal
Post by LacaK via fpc-pascal
end;
var
  c1: T1;
begin
  c1:=T2.Create;
  c1.P1; // here is called T2.P1 - runtime class type
end.
Thanks
Btw If I need for various class descendants define various class
constants, it is possible only by using class functions (getters),
where descendant class getter hides parents getter?
If they depend on the class, they're not "constants" to begin with, so a
getter function is the right approach. For such purposes I use virtual class
functions.
Yes, on other side virtual constants will be construct which I would
understand better:

If I need override some class wide parameter:

T1 = class
  private const CPORT=0; // virtual
end;

T1 = class (T2)
  private const CPORT=2; // override
end;

Now I must do:

T1 = class
  private class procedure GetPORT: integer; virtual;
end;

T2 = class(T1)
  private class procedure GetPORT: integer; override;
end;

class procedure T1.GetPORT: integer;
begin
  Result := 0;
end;

class procedure T2.GetPORT: integer;
begin
  Result := 2;
end;

I accept, that polymorphism in class inheritance work this way ...

L.


_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.fre
Michael Van Canneyt via fpc-pascal
2021-04-29 11:10:50 UTC
Permalink
Post by LacaK via fpc-pascal
Hi *,
consider the following example
T1 = class
  class procedure CP1;
  procedure P1; virtual;
end;
T2 = class(T1)
  class procedure CP1;
end;
procedure T1.P1;
begin
  CP1; // here is called allways T1.CP1, right?
  // if I want call T2.CP1 then class procedure CP1 must be also
virtual, right?
Yes
Post by LacaK via fpc-pascal
  // so Self.CP1 does not take runtime type but is staticaly resolved
at compile time to T1.CP1 ?
Yes.
For me not, it's perfectly logical.

Michael.
Jonas Maebe via fpc-pascal
2021-04-29 19:08:47 UTC
Permalink
Post by LacaK via fpc-pascal
In regular virtual method, I expect, that Self resolves to runtime class
type, thust calling CP1 should resolve to runtime type class method.
It works the same for class methods and non-class methods: no virtual =
no dynamic resolution when calling such a method.


Jonas
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.o

Loading...