Dynamische Funktionen

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Virtuelle Funktionen - Index

Dynamische Funktionen sind für von System.TObject abgeleitete Klassen zulässig. Dynamische Funktionen entsprechen virtuellen Funktionen. Sie unterscheiden sich nur in der Art und Weise der Speicherung in virtuellen Tabellen.

  • Virtuelle Funktionen besetzen einen Slot in der virtuellen Tabelle in dem Objekt, in dem sie definiert sind, und in den virtuellen Tabellen aller Nachkommen dieses Objekts.
  • Dynamische Funktionen besetzen einen Slot in allen Objekten, in denen sie definiert sind, aber in keinem Nachkommen dieser Objekte.

Dynamische Funktionen sind somit virtuelle Funktionen, die in virtuellen Tabellen gespeichert werden. Wenn Sie eine dynamische Funktion aufrufen, und diese Funktion nicht in Ihrem Objekt definiert ist, werden die virtuellen Tabellen der Vorfahrobjekte durchsucht, bis die Funktion gefunden wird.

Dynamische Funktionen verkleinern daher virtuelle Tabellen, vermindern aber zur Laufzeit die Ausführungsgeschwindigkeit, da die Adressen der Funktionen gesucht werden müssen.

Da dynamische Funktionen nur für von TObject abgeleitete Klassen zur Verfügung stehen, erhalten Sie einen Fehler, wenn Sie sie in regulären Klassen verwenden. Zum Beispiel:

class dynfunc {
  int __declspec(dynamic) bar() { return 5; }
 };

gibt den folgenden Syntaxfehler aus "Fehler: Speicherklasse 'dynamic' ist hier nicht erlaubt."

Der folgende Code dagegen wird compiliert:

#include <System.hpp>
#include <stdio.h>
class __declspec(delphiclass) func1 : public TObject {
 public:
  func1() {}
  int virtual virtbar() { return 5; }
  int __declspec(dynamic) dynbar() { return 5; }
 };
class __declspec(delphiclass) func2 : public func1 {
 public:
  func2() {}
  };
class __declspec(delphiclass) func3 : public func2 {
 public:
  func3() {}
  int virtbar() { return 10; }
  int __declspec(dynamic) dynbar() { return 10; }
 };
int main()
 { 
  func3 * Func3 = new func3; func1 * Func1 = Func3; 
  printf("func3->dynbar: %d\n", Func3->dynbar()); 
  printf("func3->virtbar: %d\n", Func3->virtbar()); 
  printf("func1->dynbar: %d\n", Func1->dynbar()); 
  printf("func1->virtbar: %d\n", Func1->virtbar()); 
  delete Func3; func2 * Func2 = new func2; 
  printf("func2->dynbar: %d\n", Func2->dynbar()); 
  printf("func2->virtbar: %d\n", Func2->virtbar()); 
  delete Func2; return 0; 
 }

Attribut dynamic ist geerbt

Im Allgemeinen arbeiten dynamische Funktionen wie virtuelle Funktionen, und das Attribut "dynamic" wird automatisch geerbt.

Wenn jedoch ein abgeleiteter Typ eine Methode mit derselben Signatur wie eine dynamische Methode in einem Basistyp deklariert, wird der Methode dieselbe dynamische ID zugewiesen, die Methode in dem abgeleiteten Typ muss aber __declspec(dynamic) enthalten. Ansonsten erzeugt der Compiler den Fehler: [BCC32-Fehler] wibwob2.cpp(21): E2113 Virtuelle Funktion 'func3::dynbar()' verursacht Konflikte mit der Basisklasse 'func1'

Sie können dies überprüfen, indem Sie das obige Beispiel ausführen. Wenn Sie die Ausgabe mit "bcc32 -S" erzeugen, können Sie die virtuellen Tabellen für func1, func2 und func3 überprüfen. func2 hat für "dynbar" KEINEN Eintrag, für "virtbar" ist aber ein Eintrag vorhanden. Trotzdem können Sie "dynbar" im func2-Objekt aufrufen:

Ausgabe:

func3->dynbar: 10
func3->virtbar: 10
func1->dynbar: 10
func1->virtbar: 10
func2->dynbar: 5
func2->virtbar: 5

Dynamische Funktionen können nicht als virtual deklariert werden und umgekehrt

Eine virtuelle Funktion kann nicht als dynamic neu deklariert werden; gleichermaßen können Sie eine dynamische Funktion nicht als virtual neu deklarieren. Die folgenden Beispiele führen zu Fehlern:

 #include <vcl.h>;
 #include <stdio.h>;
 class __declspec(delphiclass) foo1 : public TObject {
  public:
   foo1() {}
   int virtual virtbar() { return 5; }
   int __declspec(dynamic) dynbar() { return 5; }
  };
 
 class __declspec(delphiclass) foo2 : public foo1 {
  public:
   foo2() {}
   int __declspec(dynamic) virtbar() { return 10; }
   int virtual dynbar() { return 10; }
  };
 
 Error : Cannot override a virtual with a dynamic function
 
 Error : Cannot override a dynamic with a virtual function

Siehe auch