[erledigt] override create geht nicht

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut

[erledigt] override create geht nicht

Beitragvon braunbär » 18. Dez 2018, 15:39 [erledigt] override create geht nicht

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?
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Zuletzt geändert von braunbär am 19. Dez 2018, 23:00, insgesamt 1-mal geändert.
braunbär
 
Beiträge: 286
Registriert: 8. Jun 2017, 17:21

Beitragvon wp_xyz » 18. Dez 2018, 15:45 Re: override create geht nicht

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.
wp_xyz
 
Beiträge: 2918
Registriert: 8. Apr 2011, 08:01

Beitragvon braunbär » 18. Dez 2018, 16:18 Re: override create geht nicht

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.
braunbär
 
Beiträge: 286
Registriert: 8. Jun 2017, 17:21

Beitragvon Warf » 18. Dez 2018, 18:18 Re: override create geht nicht

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
Warf
 
Beiträge: 1130
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon braunbär » 18. Dez 2018, 23:48 Re: override create geht nicht

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...
braunbär
 
Beiträge: 286
Registriert: 8. Jun 2017, 17:21

• Themenende •

Zurück zu Freepascal



Wer ist online?

Mitglieder in diesem Forum: Google [Bot] und 1 Gast

porpoises-institution
accuracy-worried