Thema: Delphi virtual / override ??

Einzelnen Beitrag anzeigen

Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#21

Re: virtual / override ??

  Alt 19. Aug 2004, 17:17
Eigentlich ist es ganz simpel, wenn man den Überblick hat:

Es gibt grundsätzlich die Unterscheidung zwischen statischen und virtuellen Methoden. Die dynamischen rechne ich jetzt den virtuellen zu, da diese sich im Laufzeitverhalten nicht von den virtuellen unterscheiden.

Klassen sind im wesentlichen nichts weiter als erweiterte Records. Eine Klasse enthält zunächst einen Zeiger auf die Virtual Method Table, dann die Felder und dann die Methoden.
Statische Methoden heißen statisch, weil ihre Adresse zur Compilierzeit feststeht. Eine statische Methode wird vom Compiler also wie eine gewöhnliche Funktion behandelt, wenn der Code erzeugt wird. Es wird nur zusätzlich eine Referenz auf das bezogene Objekt mitgegeben.

Bei virtuelle Methoden dagegen wird erst zur Laufzeit die Adresse ermittelt. Das geschieht mit Hilfe der VMT (s.o)., in der u.a. die Adressen der virtuellen Methoden stehen.

Nun schaue man sich folgendes an:
Delphi-Quellcode:
type
  TMyStaticClass = class
  public
    procedure DoSomething;
  end;

  TMyStaticDerivedClass = class
  public
    procedure DoSomething;
  end;
  
  TMyVirtualClass = class
  public
    procedure DoSomething; virtual;
  end;

  TMyVirtualDerivedClass = class
  public
    procedure DoSomething; override;
  end;

procedure TMyStaticClass.DoSomething;
begin
  ShowMessage('1');
end;

procedure TMyStaticDerivedClass.DoSomething;
begin
  ShowMessage('2');
end;

procedure TMyVirtualClass.DoSomething;
begin
  ShowMessage('3');
end;

procedure TMyVirtualDerivedClass.DoSomething;
begin
  ShowMessage('4');
end;

So, jetzt probieren wir etwas rum:
Delphi-Quellcode:
var
  o: TMyStaticClass;
begin
  o := TMyStaticDerivedClass.Create;
  o.DoSomething;
end;
Hier wird '1' ausgegeben. Warum, es wird doch eine Instanz von TMyStaticDerviedClass erzeugt? Ja, aber der Typ der Variablen ist TMyStaticClass, und Typen werden zur Compilierzeit ausgewertet.

Schauen wir uns das ganze mal virtuell an:
Delphi-Quellcode:
var
  o: TMyVirtualClass;
begin
  o := TMyVirtualDerivedClass.Create;
  o.DoSomething;
end;
Hier wird nun 4 ausgegeben. Wir erinnern uns, jedes Objekt enthält einen Zeiger auf die VMT. Dadurch kann zur Laufzeit, obwohl der tatsächliche Typ unbekannt bzw. maskiert ist, die Adresse der entsprechenden virtuelle Methode ermittelt werden.


Nun zu override:
Um zu kennzeichnen, dass wir eine virtuelle Methode überschreiben wollen, müssen wir dem override angeben. Die Methode bleibt dadurch virtuell, keine Angst. Geben wir aber kein override an, so verdecken wir die virtuelle Methode. Der Compiler teilt uns das mit, weil er denkt, wir wollen das nicht so. Wenn wir das aber doch wollen, müssen wir ihm das explizit sagen, und dafür ist reintroduce da.
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat