[erledigt] override create geht nicht

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

[erledigt] override create geht nicht

Beitrag von braunbär »

Entweder ich habe hier einen völlig blinden Fleck oder der FPC hat einen Fehler, wobei mir letzteres an dieser Stelle gar nicht möglich erscheint.

Die Klasse TStrings hat einen public constructor Create

Code: Alles auswählen

 
  TStrings = class(TPersistent)
  private
    ...
  protected
    ...
  public
    constructor Create;
    ...
 


Die Klasse TStringList ist von TStrings abgeleitet, und erbt den Constructor. Im Zuge der Änderungen würde ich gerne den geerbten Constructor überschreiben:

Code: Alles auswählen

 
  TStringList = class(TStrings)
  private
    ...
  protected
    ...
  public
    constructor Create; override;
    destructor Destroy; override;
 


Und hier meldet mir der FPC einen Fehler, s. angegehängte Graphik? Was ist da falsch?
Dateianhänge
override.PNG
Zuletzt geändert von braunbär am Mi 19. Dez 2018, 23:00, insgesamt 1-mal geändert.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: override create geht nicht

Beitrag von wp_xyz »

Der letztendlich von TObject geerbte Constructor ist nicht virtuell, daher ist der Zusatz "override" fehl am Platz. Erst ab TComponent gibt es einen virtuellen Constructor.

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: override create geht nicht

Beitrag von braunbär »

Tut mir leid, jetzt ist Zeit für eine Pause. Der Fehler war ein ganz anderer. Ich hatte den Constructor schon einmal geschrieben, jetzt etwas weiter vorne im Code ein zweites mal. Hat natürlich eine Fehlermeldung gegeben, und ich habe gemeint, es würde an einem fehlenden override liegen, das er dann aber natürlich auch beanstandet hat.

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: override create geht nicht

Beitrag von Warf »

Einen nicht virtuellen Konstruktur musst du nicht überschreiben. Das macht auch absolut keinen Sinn. Kurze Erklärung wie virtual und override funktionieren und warum es unsinn ist einen nicht virutellen Konstruktor zu überschreiben. Virtuelle funktionen stehen im Objekt das man erzeugt in der so genannten virtual function table (vtable). Wenn diese Funktion aufgerufen wird schaut der PC im der vtable nach wo die funktion liegt und springt dort hin. Wenn man nun eine override funktion definiert, überschreibt den eintrag für die Funktion in der vtable, sodass statt der original funktion die abgeleitete Funktion aufgerufen wird, egal ob an dieser stelle bekannt ist um was für ein Objekt es sich handelt. Sagen wir Klasse TFoo hat die virtuelle Methode FooBar, mit grundfunktionalität. Klasse TBar erbt von TFoo und möchte nun spezielle Funktionalität implementieren überschreibt also FooBar. Wenn jetzt irgendwo Foo.FooBar(); (Foo: TFoo) denkt der Compiler zwar das es sich um ein Objekt des Typs TFoo handelt, und würde ohne virtual einfach TFoo.FooBar aufrufen, aber weil es virtual ist, wird der Umweg über die vtable gemacht, wo die Klasste TBar ihre eigene funktion reingeschrieben hat, und so wird TBar.FooBar ausgeführt.

Damit das ganze funktionieren kann, verspricht man mit dem Virtual Keyword, das alle überschreibenden Funktionen die Selbe Signatur (Rückgabewert und Parameter) haben, also identisch aufgerufen werden können.

So setzt man z.B. konstruktoren virtuell um zu garantieren das der Korrekte konstruktor auf jeden fall ausgeführt werden muss. Ansonsten macht override bei einem Konstruktor aber keinen sinn, der Konstruktor erzeugt das Objekt, es gibt vorher das Objekt also noch nicht, damit gibt es auch noch keine vtable, weshalb überschreiben im ursprünglichen Sinne nicht mal funktioniert.
Du kannst nicht über eine der Vaterklassen den Konstruktor einer Kindsklasse aufrufen, das ist technisch nicht möglich, da man immer den Konstruktor der aktuellen klasse aufrufen muss. Daher ist der einzige Grund konstruktoren zu überladen, um sicher zu gehen die richtige Signatur für den Konstruktor verwendet wird.

Langer rede kurzer Sinn, verwende kein override, es macht für dich keinen Sinn

braunbär
Beiträge: 369
Registriert: Do 8. Jun 2017, 18:21
OS, Lazarus, FPC: Windows 10 64bit, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: 64Bit
Wohnort: Wien

Re: override create geht nicht

Beitrag von braunbär »

Danke für die ausführliche Erklärung, im Prinzip war mir das Ganze schon klar, und ich hatte auch ursprünglich weder virtual noch override verwendet. Nachdem ich eine Fehlermeldung bekommen habe, die mich irgendwie dazu gebracht hat, zu glauben, der Compiler will hier ein override haben - war natürlich Unsinn - habe ich es so versucht, und bei der neuerlichen Fehlermeldung (es geht also weder mit noch ohne override - was nun?) war dann irgendwie Kurzschluss. An die Möglichkeit, dass ich den Konstruktor ohnehin schon geschrieben haben könnte und der Code jetzt zwei mal da steht, habe ich überhaupt nicht gedacht.

Ich sollte mir angewöhnen, in solchen Situationen einfach eine kurze Pause zu machen und das Ganze danach noch einmal in aller Ruhe anzuschauen...

Antworten