6.3.2 Class fields/variables

Similar to objects, a class can contain static fields or class variables: these fields or variables are global to the class, and act like global variables, but are known only as part of the class. They can be referenced from within the classes’ methods, but can also be referenced from outside the class by providing the fully qualified name.

Again, there are two ways to define class variables. The first one is equivalent to the way it is done in objects, using a static modifier:

For instance, the output of the following program is the same as the output for the version using an object:

{$mode objfpc}
type
  cl=class
    l : longint;static;
  end;
var
  cl1,cl2 : cl;
begin
  cl1:=cl.create;
  cl2:=cl.create;
  cl1.l:=2;
  writeln(cl2.l);
  cl2.l:=3;
  writeln(cl1.l);
  Writeln(cl.l);
end.

The output of this will be the following:

2
3
3

Note that the last line of code references the class type itself (cl), and not an instance of the class (cl1 or cl2).

In addition to the static field approach, in classes, a Class Var can be used. Similar to the way a field can be defined in a variable block, a class variable can be declared in a class var block:

{$mode objfpc}
type
  cl=class
  class var
    l : longint;
  end;

This definition is equivalent to the previous one.

Note that a class variable is tied to a specific class. Descendent classes will refer to the same instance, unless the variable is redeclared. The following program demonstrates this:

{$mode objfpc}
type
  TA = class // base type
    class var CODE: integer;
  end;
  TB = class(TA);
  TC = class(TA);

begin
  TA.Code:=0;
  TB.Code:=1;
  TC.Code:=2;
  Writeln(Ta.Code:2,Tb.Code:2,Tc.code:2);
end.

The output of this program is:

 2 2 2

Because it is tied to a class, it can be overridden in Delphi mode:

{$mode delphi}
type
  TA = class // base type
    class var CODE: integer;
  end;
  TB = class(TA)
    Class var code : integer;
  end;
  TC = class(TA)
    Class var code : integer;
  end;

begin
  TA.Code:=0;
  TB.Code:=1;
  TC.Code:=2;
  Writeln(Ta.Code:2,Tb.Code:2,Tc.code:2);
end.

It will print the following:

 0 1 2

However, in OBJFPC mode it will not compile, and will give a duplicate identifier error.