[gelöst] Verwendung von class of mit und ohne explizitem Typecast

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1805
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Verwendung von class of mit und ohne explizitem Typecast

Beitrag von fliegermichl »

PascalDragon hat geschrieben: Di 28. Jul 2026, 20:51
fliegermichl hat geschrieben: Mo 27. Jul 2026, 10:23 Das folgende Programm erstellt eine Kopie einer Klasse unter Verwendung von class of.
Dabei einmal mit explizitem Typecast und einmal ohne.

Bei der Verwendung ohne den Typecast wird zwar die korrekte Klasse erzeugt, aber deren Constructor nicht aufgerufen.
Soll das so sein und wenn ja - wieso?

Das Problem ist, daß imn zweiten Fall nur TObject.Create aufgerufen wird und damit fList = nil ist.
Ja, das soll so, da der Typ von TObject.ClassType TClass ist und TClass hat keinen virtuellen Konstruktor. Wenn du ClassType zu TBaseClass castest, dann wird durch Create der virtuelle Konstruktor von TBase aufgerufen.
Irgendwie eben nicht. classType liefert nicht TClass sondern TBase. Selbst wenn ich TBaseclass nicht explizit definiere.

Code: Alles auswählen

program Project1;
type

  TBase = class
  end;

var c : TBase;
begin
  c := TBase.Create;
  writeln(c.ClassType.ClassName);
  Readln;
end.
Liefert die Ausgabe TBase.

Benutzeravatar
Zvoni
Beiträge: 717
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Verwendung von class of mit und ohne explizitem Typecast

Beitrag von Zvoni »

fliegermichl hat geschrieben: Mi 29. Jul 2026, 07:54 Irgendwie eben nicht. classType liefert nicht TClass sondern TBase.
Irgendwie aber doch.
PascalDragon bezieht sich explizit auf den Constructor

teste mal

Code: Alles auswählen

program Project1;
{$mode objfpc}{$H+}
Uses Classes;
Type
  TBase=Class

  end;
Var
  a,b:TBase;
begin
  a:=TBase.Create;
  b:=a.ClassType.Create;  //Compile-Error!
  Writeln(a.ClassName);
  Writeln(B.ClassName);
  Readln;
end.
Es gibt nen Compiler-Fehler:
project1.lpr(12,7) Error: Incompatible types: got "TObject" expected "TBase"

so aber

Code: Alles auswählen

program Project1;
{$mode objfpc}{$H+}
Uses Classes;
Type
  TBase=Class
  end;
  TBaseClass=Class of TBase;
Var
  a,b:TBase;
begin
  a:=TBase.Create;
  b:=TBaseClass(a.ClassType).Create;
  Writeln(a.ClassName);
  Writeln(B.ClassName);
  Readln;
end.
läuft sauber durch, und das Ergebnis ist korrekt.
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1805
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Verwendung von class of mit und ohne explizitem Typecast

Beitrag von fliegermichl »

Zvoni hat geschrieben: Mi 29. Jul 2026, 09:18
fliegermichl hat geschrieben: Mi 29. Jul 2026, 07:54 Irgendwie eben nicht. classType liefert nicht TClass sondern TBase.
Irgendwie aber doch.
PascalDragon bezieht sich explizit auf den Constructor
...

Code: Alles auswählen

  a:=TBase.Create;
  b:=a.ClassType.Create;  //Compile-Error!
Ja, das mit dem Compileerror hatte ich auch schon gesehen.
D.h., dass zur Compilezeit der Compiler meint, er gibt TClass in Classtype zurück, zur Laufzeit liefert er dann aber doch TBase.

Naja, wie auch immer. Ich konnte ja das für mich gewünschte Verhalten mit dem Typecast erreichen.
Von dem her case closed.

PascalDragon
Beiträge: 1047
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Verwendung von class of mit und ohne explizitem Typecast

Beitrag von PascalDragon »

fliegermichl hat geschrieben: Mi 29. Jul 2026, 07:54
PascalDragon hat geschrieben: Di 28. Jul 2026, 20:51
fliegermichl hat geschrieben: Mo 27. Jul 2026, 10:23 Das folgende Programm erstellt eine Kopie einer Klasse unter Verwendung von class of.
Dabei einmal mit explizitem Typecast und einmal ohne.

Bei der Verwendung ohne den Typecast wird zwar die korrekte Klasse erzeugt, aber deren Constructor nicht aufgerufen.
Soll das so sein und wenn ja - wieso?

Das Problem ist, daß imn zweiten Fall nur TObject.Create aufgerufen wird und damit fList = nil ist.
Ja, das soll so, da der Typ von TObject.ClassType TClass ist und TClass hat keinen virtuellen Konstruktor. Wenn du ClassType zu TBaseClass castest, dann wird durch Create der virtuelle Konstruktor von TBase aufgerufen.
Irgendwie eben nicht. classType liefert nicht TClass sondern TBase. Selbst wenn ich TBaseclass nicht explizit definiere.
Das ist richtig, aber für die Auflösung von Konstruktoren von Klassentypen ist der Compiletime Typ relevant. Ein Kindkonstruktor wird nur verwendet, wenn der Konstruktor der im class of verwendeten Klasse virtual ist.
FPC Compiler Entwickler

Antworten