AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Warum virtual / override bei destructor / constructor?
Thema durchsuchen
Ansicht
Themen-Optionen

Warum virtual / override bei destructor / constructor?

Ein Thema von HJay · begonnen am 22. Mai 2017 · letzter Beitrag vom 14. Jan 2023
Antwort Antwort
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#1

AW: Warum virtual / override bei destructor / constructor?

  Alt 22. Mai 2017, 11:19
Virtual bei Create benötigt man z.b. in folgendem Falle:
Delphi-Quellcode:
type
  TBaseClass = class(TObject)
  public
    constructor Create; virtual;
  end;

  TClassA = class(TBaseClass)
  public
    constructor Create; override;
  end;

  TClassB = class(TBaseClass)
  public
    constructor Create; override;
  end;

  TClassType = class of TBaseClass;

..

function DynamicCreate(ClassType: TClassType): TBaseClass;
begin
  Result := ClassType.Create;
end;
Hätte man den Constructor hier nicht als virtual deklariert, würde immer Der von TBaseClass aufgerufen. Mit virtual ruft die Funktion korrekt den Constructor der konkreten Klasse auf.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
HJay

Registriert seit: 7. Dez 2009
172 Beiträge
 
Delphi XE7 Enterprise
 
#2

AW: Warum virtual / override bei destructor / constructor?

  Alt 22. Mai 2017, 11:28
Das bedeutet dann aber auch, dass die Entwicklung der Unit System problemlos sowohl den Constructor Create als auch den Destructor Destroy hätten analog mit "virtual" deklarieren können und alles funktionieren würde? Ist das so?

Dieses Analogie der Deklarationen würde sicherlich vielen Anfängern Irritationen ersparen.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#3

AW: Warum virtual / override bei destructor / constructor?

  Alt 22. Mai 2017, 11:32
Das bedeutet dann aber auch, dass die Entwicklung der Unit System problemlos sowohl den Constructor Create als auch den Destructor Destroy hätten analog mit "virtual" deklarieren können und alles funktionieren würde? Ist das so?

Dieses Analogie der Deklarationen würde sicherlich vielen Anfängern Irritationen ersparen.
Allerdings ist man bei einem virtuellen Konstruktor beim override an die Parameter-Signatur des Vorgängers gebunden. Natürlich kann man trotzdem neue, nicht-virtuelle Konstruktoren einführen, aber das wäre dann für noch mehr Anfänger noch viel verwirrender.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
HJay

Registriert seit: 7. Dez 2009
172 Beiträge
 
Delphi XE7 Enterprise
 
#4

AW: Warum virtual / override bei destructor / constructor?

  Alt 22. Mai 2017, 11:43
OK, danke.

Warum kann man den "constructor create" überschreiben, ohne "reintroduce" angeben zu müssen? Müsste das nicht kollidieren?

Wenn auch ohne "virtual/override" eine Vorfahrprozedur überschrieben und verdeckt werden kann und trotzdem mittels "inherited" die Vorfahrprozedur aufgerufen werden kann, dann verstehe ich eigentlich nicht, wozu man überhaupt "virtual/override" braucht?
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
781 Beiträge
 
#5

AW: Warum virtual / override bei destructor / constructor?

  Alt 22. Mai 2017, 11:51
Warum kann man den "constructor create" überschreiben, ohne "reintroduce" angeben zu müssen? Müsste das nicht kollidieren?
Weil nicht virtual benutzt wurde.

Wenn auch ohne "virtual/override" eine Vorfahrprozedur überschrieben und verdeckt werden kann und trotzdem mittels "inherited" die Vorfahrprozedur aufgerufen werden kann, dann verstehe ich eigentlich nicht, wozu man überhaupt "virtual/override" braucht?
Lies dir nochmals genau die Antworten durch.

Der Unterschied ist, ob zur Laufzeit die Methode des echten Typs (ggf. Nachfahren) oder die des Variablentyps aufgerufen wird
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.045 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: Warum virtual / override bei destructor / constructor?

  Alt 22. Mai 2017, 11:48
Was Zacherl gezeigt hat, sieht man zum Beispiel bei TComponent. Dort ist der Konstructor virtual, was benötigt wird, wenn vom Streaming Mechanismus (Form wird aus dfm geladen) die ganzen Komponenten erstellt werden.

Wäre TObject.Create virtual, müsste man jegliche Klasse über TClass erzeugen können, obwohl diese Klasse möglicherweise gar keinen parameterlosen Konstruktor haben soll.
Aktuell gibt es nur den kleinen haken, dass ein Create auf einer TClass variable fest TObject.Create aufruft, was weitaus weniger schlimm ist.

Warum kann man den "constructor create" überschreiben, ohne "reintroduce" angeben zu müssen? Müsste das nicht kollidieren?
Verwechsle nicht die Begriffe, "überschreiben" (override) kann man nur virtuelle Methoden - ein reintroduce ist lediglich ein Hinweis an den Compiler nach dem Motto - ich weiß, was ich tue (damit der keine Warning W1010 generiert). Alles andere ist verdecken einer Methode. Und da TObject.Create nunmal nicht virtual ist, gibts auch kein reintroduce.

Mir scheint, da sind noch ein paar Wissenslücken bzgl OOP/Polymorphie verhanden, die das Verständnis etwas erschweren.

P.S. Da sieht man mal, warum C# es erforderlich macht, auf jeder Klasse explizit einen Konstruktor zu definieren (selbst wenn er nix macht). Weil implizit einen erben nur verwirrt und zu Defekten führen kann.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (22. Mai 2017 um 11:54 Uhr)
  Mit Zitat antworten Zitat
HJay

Registriert seit: 7. Dez 2009
172 Beiträge
 
Delphi XE7 Enterprise
 
#7

AW: Warum virtual / override bei destructor / constructor?

  Alt 22. Mai 2017, 14:14
Mir scheint, da sind noch ein paar Wissenslücken bzgl OOP/Polymorphie verhanden, die das Verständnis etwas erschweren.
Korrekt. Nun, ich versuche ja gerade, diese Lücken zu füllen... ich programmiere schon lange in OOP, aber gewisse Details leuchten mir einfach partout nicht ein, egal wie viel ich darüber lese.

Delphi-Quellcode:
 TMyParent = class(TObject)
  public
    procedure Something;
  end;

  TMyChild = class(TMyParent)
  public
    procedure Something;
  end;

implementation

{ TMyParent }

procedure TMyParent.Something;
begin
  Form1.Memo1.Lines.Add('Parent');
end;

{ TMyChild }

procedure TMyChild.Something;
begin
  inherited Something;
  Form1.Memo1.Lines.Add('Child');
end;
Nehmen wir mal diesen trivialen Fall. Alles Funktioniert. Keine Warnungen durch den Compiler. Man kann auch in der Child-Klasse die Parent-Methode mittels inherited nutzen.

Auch wenn ich nun beim Parent ein "virtual" hinzufüge, ändert sich nichts am Verhalten des Programms, außer dass es eine W1010 Warnung vom Compiler gibt.

Die Methode "Something" wird mit und ohne "virtual" verdeckt und die verdeckte Methode kann so oder so mit "inherited" verwendet werden.

Wieso ist sie angeblich in dem einen Fall "verdeckt" und im anderen Fall nicht? Was bringt die Angabe von "virtual", wenn man die Methode doch ohnehin mittels inherited weiter verwenden kann?

Delphi-Quellcode:
 TMyParent = class(TObject)
  public
    procedure Something; virtual;
  end;

 TMyChild = class(TMyParent)
  public
    procedure Something; { kein "override" nötig! }
  end;
Was ändert sich durch "virtual"?

In so vielen Büchern steht, dass eine abgeleitete Klasse eine virtuelle Prozedur überschreiben kann. Aber das geht doch auch ohne "virtual", siehe Beispiel!

Oder zurück zur Titelfrage: Was würde passieren, wenn "TObject.Destroy" nicht virtual deklariert wäre und abgeleitete Klassen einfach wie im obigen Beispiel Destroy neu implementieren und über inherited die Parent-Prozedur aufrufen würden? Wäre irgendwas anders, als es jetzt ist?

Geändert von HJay (22. Mai 2017 um 14:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
781 Beiträge
 
#8

AW: Warum virtual / override bei destructor / constructor?

  Alt 22. Mai 2017, 14:23
Delphi-Quellcode:
procedure Test;
var
  A: TMyParent;
begin
  A := TMyChild.Create;
  try
    A.Something;
  finally
    A.Free;
  end;
end;
Das führst jetzt einmal ohne und einmal mit virtual+override aus, dann siehst du im Ergebnis den Unterschied.
  Mit Zitat antworten Zitat
HJay

Registriert seit: 7. Dez 2009
172 Beiträge
 
Delphi XE7 Enterprise
 
#9

AW: Warum virtual / override bei destructor / constructor?

  Alt 22. Mai 2017, 14:31
Vielen Dank, OK, das verstehe ich jetzt! Gute Erklärung als Beispiel!

Umso mehr erscheint es doch aber dann als Fehler, dass TObject.Create eben gerade nicht virtuell deklariert ist...? Das war ja die Titelfrage dieses Threads...
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz