Home >Documents >Early binding (frühe Bindung) late binding (späte Bindung)

Early binding (frühe Bindung) late binding (späte Bindung)

Date post:06-Apr-2015
Category:
View:105 times
Download:3 times
Share this document with a friend
Transcript:
  • Folie 1
  • early binding (frhe Bindung) late binding (spte Bindung)
  • Folie 2
  • Ausgangspunkt sind wieder die Klassen der letzten Prsentation:
  • Folie 3
  • #include "stdafx.h" #include using namespace std; class A{ public: A(int i); void hallo(); int x; }; class B: public A{ public: B(int i); void hallo(); int x; int y; };
  • Folie 4
  • A::A(int i){ x = i; }; void A::hallo(){ cout
  • Adr a 0100x10 Adr b 0200A::x18 x19 y20 Adr ap 03000200 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; A a(10); B b(20); A *ap;
  • Folie 9
  • Auf welches x wrde dann die Anweisung ap->x = 13 zugreifen ? Es gibt 2 Mglichkeiten: b.A::x oder b.B::x Da sich der Compiler schon beim Compilieren (und nicht erst whrend der Laufzeit) entscheiden muss, kann es nicht... Adr a 0100x10 Adr b 0200A::x18 x19 y20 Adr ap 03000200 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; A a(10); B b(20); A *ap;
  • Folie 10
  • .... B::x sein, da diese Komponente (falls ap auf a zeigt) nicht existiert. Dagegen existiert (egal ob ap auf a oder b zeigt) immer die Komponente A::x. Diesen Vorgang des Compilers nennt man early binding (frhe Bindung). dieses x existiert in a und b Adr a 0100x10 Adr b 0200A::x18 x19 y20 Adr ap 03000200 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; A a(10); B b(20); A *ap;
  • Folie 11
  • Also wird der Wert von x im Objekt b verndert auf: Adr a 0100x10 Adr b 0200A::x18 x19 y20 Adr ap 03000200 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; A a(10); B b(20); A *ap;
  • Folie 12
  • Adr a 0100x10 Adr b 0200A::x x19 y20 Adr ap 03000200 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; A a(10); B b(20); A *ap;
  • Folie 13
  • Adr b 0200A::x13 x19 y20 Also: Der Typ der Zeigervariablen, hier also A, und nicht der Typ des Objekts auf den ap whrend der Laufzeit zeigt, hier also B, bestimmt welches Mitglied (Member) von *ap angesprochen wird. Adr ap 03000200 Adr a 0100x10 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; A a(10); B b(20); A *ap;
  • Folie 14
  • Neue Frage
  • Folie 15
  • Welcher Wert welcher Speicherzelle wird durch die folgenden Anweisungen links verndert ? Auf welches Objekt (a oder b) zeigt ap ? aus Platzgrnden: hier steht wie vorher: rand()%2 = =1 Vom Zufall abhngig, zeigt ap entweder auf das Objekt a oder auf das Objekt b. Adr a 0100x10 hallo() Adr b 0200A::x18 x19 y20 A::hallo() B::hallo() Adr ap 0300? if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 16
  • Angenommen, ap zeigt auf b. Welchen Wert hat dann ap ? Adr a 0100x10 hallo() Adr ap 0300? Adr b 0200A::x18 x19 y20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 17
  • Adr a 0100x10 hallo() Adr ap 0300 Adr b 0200A::x18 x19 y20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 18
  • Adr a 0100x10 hallo() Adr ap 03000200 Adr b 0200A::x18 x19 y20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 19
  • Auf welches hallo() wrde dann die Anweisung ap->hallo() zugreifen ? Es gibt 2 Mglichkeiten: b.A::hallo() oder b.B::hallo() Da sich der Compiler schon beim Compilieren (und nicht erst whrend der Laufzeit) entscheiden muss, kann es nicht... Adr a 0100x10 hallo() Adr ap 03000200 Adr b 0200A::x18 x19 y20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 20
  • .... B::hallo() sein, da diese Methode (falls ap auf a zeigt) nicht zu A gehrt. Dagegen existiert (egal ob ap auf a oder b zeigt) immer die Methode A::hallo(). Diesen Vorgang des Compilers nennt man early binding (frhe Bindung). dieses hallo() existiert in a und b Adr ap 03000200 Adr a 0100x10 hallo() Adr b 0200A::x18 x19 y20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 21
  • Also: Der Typ der Zeigervariablen, hier also A, und nicht der Typ des Objekts auf den ap whrend der Laufzeit zeigt, hier also b, bestimmt welches Mitglied (Member) von *ap angesprochen wird. Adr a 0100x10 hallo() Adr ap 03000200 Adr b 0200A::x18 x19 y20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 22
  • Mgliche Speicherbelegung beim obigen Programm (hier nochmals das Programm)
  • Folie 23
  • int main(){ A a(10); B b(20); A *ap; srand((unsigned)time(NULL)); if(rand()%2==1){ ap = &a; } else{ ap = &b; } ap->x = 13; ap->hallo(); return(0); }
  • Folie 24
  • Annahme: 1) Die Adressen wurden willkrlich gewhlt. In der 4. Spalte stehen die Werte also die Inhalte der Adressen nachdem die letzte Anweisung des Programms abgearbeitet wurde. 2) Zufallsbedingt soll der Krper des else Teils der if-Verzweigung (also ap = &b) ausgefhrt werden.
  • Folie 25
  • AdresseSymbolbestehtInhalt 0100ax10... 0200bA::x13 B::x19 y20... 0300ap0200... 0500 A::hallo() Anweisungen... 0600 B::hallo() Anweisungen
  • Folie 26
  • Neue Frage
  • Folie 27
  • Wie kann man erreichen, dass bei einem Verweis auf ein Objekt die Methode der Klasse dieses Objektes zur Laufzeit aufgerufen wird und nicht die gleichnamige Methode der Klasse des Typs des Verweises beim Compilieren ? Kurz: Wie kann man early binding umgehen ? Wie wird dies programmtechnisch realisiert ?
  • Folie 28
  • Angenommen, ap zeigt zufallsbedingt auf a. Dann soll die Anweisung ap->hallo() auf die folgende Methode zugreifen: Die Methode hallo(), der Klasse des Objekts, auf das ap whrend der Laufzeit zeigt, also A::hallo(). Adr a 0100x10 hallo() Adr ap 03000100 Adr b 0200A::x18 x19 y20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 29
  • Angenommen, ap zeigt zufallsbedingt auf b. Dann soll die Anweisung ap->hallo() auf die folgende Methode zugreifen: Die Methode hallo(), der Klasse des Objekts, auf das ap whrend der Laufzeit zeigt, also B::hallo(). Adr a 0100x10 hallo() Adr ap 03000200 Adr b 0200A::x18 x19 y20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 30
  • Das dazugehrige Programm ist das Gleiche wie oben, nur dass die Methode hallo() bei der Deklaration den Bezeichner virtual bekommt.
  • Folie 31
  • Das Programm
  • Folie 32
  • #include "stdafx.h" #include #include using namespace std;
  • Folie 33
  • class A{ public: A(int i); virtual void hallo(); int x; }; class B: public A{ public: B(int i); virtual void hallo(); int x; int y; }; Durch den Bezeichner virtual wird hallo() eine virtuelle Funktion. Die Verwendung von virtual ist nur innerhalb einer Klassendeklaration zulssig. Der Bezeichner virtual vererbt sich und mu daher nicht mehr (kann aber) in den Subklassen wiederholt werden.
  • Folie 34
  • A::A(int i){ x = i; }; void A::hallo(){ cout
  • vt_A ist ein Verweis (Adresse) auf eine Tabelle (virtual function pointer table), in der wiederum die Adressen der virtuellen Methoden der Klasse A stehen, hier also die Adresse der Methode A::hallo() vt_B ist ein Verweis (Adresse) auf eineTabelle (virtual function pointer table), in der wiederum die Adressen der virtuellen Methoden der Klasse B stehen, hier also die Adresse der Methode B::hallo() Adr vt_A 0500 A::hallo() Adr vt_B 0600 B::hallo() Adr a 096&vt_A 0100x10 Adr ap 0300? Adr b 0196&vt_B 0200A::x18 x19 y20 if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 39
  • Adr vt_A 0500 A::hallo() Adr vt_B 0600 B::hallo() Adr a 096&vt_A 0100x10 Adr ap 0300? Adr b 0196&vt_B 0200A::x18 x19 y20 if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap; Angenommen, ap zeigt zufallsbedingt auf a. Welchen Wert hat dann ap ?
  • Folie 40
  • Adr vt_A 0500 A::hallo() Adr vt_B 0600 B::hallo() Adr a 096&vt_A 0100x10 Adr ap 0300 Adr b 0196&vt_B 0200A::x18 x19 y20 if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap;
  • Folie 41
  • Adr vt_A 0500 A::hallo() Adr vt_B 0600 B::hallo() Adr a 096&vt_A 0100x10 Adr ap 0300100 Adr b 0196&vt_B 0200A::x18 x19 y20 if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap; Welche Adresse wird dann beim Aufruf von hallo() in der folgenden Anweisung angesprochen ? ap->hallo() ein ?
  • Folie 42
  • Adr vt_A 0500 A::hallo() Adr vt_B 0600 B::hallo() Adr a 096&vt_A 0100x10 Adr ap 0300100 Adr b 0196&vt_B 0200A::x18 x19 y20 if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap; *(ap-4) 0100 096 0500 Welche Methode wird also aufgerufen ? A::hallo()
  • Folie 43
  • Adr vt_A 0500 A::hallo() Adr vt_B 0600 B::hallo() Adr a 096&vt_A 0100x10 Adr ap 0300? Adr b 0196&vt_B 0200A::x18 x19 y20 if(...) ap = &a; else ap = &b; ap->hallo(); A a(10); B b(20); A *ap; Angenommen, ap zeigt zufallsbedingt auf b. Welchen Wert hat dann ap ?
Embed Size (px)
Recommended