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

Slides:



Advertisements
Ähnliche Präsentationen
Einführung in die Programmiersprache C/C++
Advertisements

Programme in C++.
der Universität Oldenburg
Funktionen.
Kritische Betrachtung
Seminar: "Einführung in C/C++" Einführung in die Programmiersprache C/C++ Donnerstag Andreas Döring SS 2004.
Gliederung des Inhalts
Java: Objektorientierte Programmierung
Indirekte Adressierung
Java: Grundlagen der Objektorientierung
SWITCH - Anweisung.
Klassenvariable (auch Klassendaten bzw. statische Attribute genannt) und statische Methoden.
Dateien. Eine Datei wird in C++ als ein Stream, also als ein Objekt einer bestimmten Klasse dargestellt.
Dynamischer Speicher. Ein Vergleich aus dem täglichen Leben...
Ein Beispiel in Java.
Dynamisches Array als "verkettete Liste". Ein Vergleich.
Erweiterte Zuweisungskompatibilität
Dynamischer Speicher und Struktur
Klassenvariable. Da man für jede Kuh bzw. jede Henne auf dem Markt den gleichen Preis für ein Liter Milch, bzw. den gleichen Preis für ein Ei bekommt,
Konstruktoren.
Objekte werden als Adressen (Referenzen) übergeben. Dies führt manchmal zu unerwarteten Ergebnissen...
Parameterübergabe von zweidimensionalen Feldern in Funktionen.
Vererbung. Das Prinzip der Vererbung im täglichen Leben:
Polymorphie (Vielgestaltigkeit)
Assoziationen (Beziehungen). Zwischen Objekten kann es eine Beziehung geben.
Polymorphie (Vielgestaltigkeit)
Objekte und Arbeitsspeicher
Der Präprozessor. Bevor der Compiler das Programm in Maschinencode übersetzt (nur dieser kann von der CPU, dem Herz des Computers, bearbeitet werden)
FOR Anweisung. Aufgabe : Ausgabe aller ganzen Zahlen von 0 bis 100 auf dem Bildschirm.
Dynamischer Speicher. In einer Funktion wird z.B. mit der Deklaration int i; Speicher auf dem sogenannten Stack reserviert. Wenn die Funktion verlassen.
DO...WHILE Anweisung.
Praktikum Entwicklung und Einsatz von Geosoftware I - Sitzung 3 Klassen, Objekte, Arrays und Kontrollstrukturen Sommersemester 2003 Lars Bernard.
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 7 Claudio Moraga, Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
Imperative Programmierung Funktionen und Parameter
Programmieren mit JAVA
Vererbung Spezialisierung von Klassen in JAVA möglich durch
PKJ 2005/1 Stefan Dissmann Ausblick Es fehlen noch: Möglichkeiten zum Strukturieren größerer Programme Umgang mit variabler Zahl von Elementen Umgang mit.
Zusammenfassung Vorwoche
Abstrakter Datentyp in C++ I - Klasse -
Objektorientierte Programmierung
Der C-Präprozessor EDV1 - 04Präprozessor.
DVG Einführung in Java1 Einführung in JAVA.
Guten Nachmittag!.
Wir haben gesehen Das Gerüst ist bei JavaKara fix vorgegeben
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Einführung in die Programmierung
Einführung in die Programmiersprache C 4
Informatik 1 Letzte Übung.
Auswahlanweisungen, Iterationsanweisungen, Blöcke, Sprunganweisungen
Programmbereich, zu dem eine Deklaration gehört Arten von Gültigkeitsbereichen -Namespace : Deklarationen von Klassen, Interfaces, Structs, Enums, Delegates.
Polymorphie (Vielgestaltigkeit). Wenn eine Methode, wie z.B. print für verschiedene Programmteile steht (und z.B. einmal Objekte verschiedener Klassen.
Erweiterte Zuweisungskompatibilität. Wie kann man Objekte verschiedener Klassen einer Klassenhierarchie einander zuweisen ?
Funktionen. Aufgabe : Eingabe zweier Zahlen ---> Minimum bestimmen Dann nochmals Eingabe zweier Zahlen ---> Minimum bestimmen.
Pointer. Grundsätzliches: Im Arbeitsspeicher werden Daten gespeichert. Um auf die Daten eindeutig zugreifen zu können, werden diesen Daten Adressen zugeordnet.
Funktionen, Felder und Parameter- übergabe. Funktionsaufruf mit Feld als Parameter: Parameter = Name des Feldes.
Namensräume (namespaces). verwendet man umfangreiche eigene und fremde Bibliotheken (Sammlungen von Funktionen) so ist die Wahrscheinlichkeit groß, daß.
Java Programme nur ein bisschen objektorientiert.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
C++ FÜR cOMPUTERSPIELENTWICKLER
Tutorium Software-Engineering SS14 Florian Manghofer.
Funktionen (Zweck und Eigenschaften) Funktionen sind Unterprogramme, die einen bestimmten Zweck erfüllen Sie zerlegen Probleme in kleine, abgeschlossene.
Tutorium Software-Engineering SS14 Florian Manghofer.
Konstruktoren.
Referenzen In c kennen wir gewöhnliche Variablen und Pointer.
Einführung in die Programmierung
Implementieren von Klassen
 Präsentation transkript:

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

Ausgangspunkt sind wieder die Klassen der letzten Präsentation:

#include "stdafx.h" #include <iostream> #include <time.h> using namespace std; class A{ public: A(int i); void hallo(); int x; }; class B: public A{ B(int i); int y;

A::A(int i){ x = i; }; void A::hallo(){ cout << "Ich bin A" << "x=" << x << endl; B::B(int i):A(i-2){ x = i-1; y = i; void B::hallo(){ cout << "Ich bin B" << "x=" << x << "y=" << y << endl;

a b ap Adr 0100 x 10 Adr 0200 A::x 18 x 19 y 20 Adr 0300 ? A a(10); B b(20); A *ap; Adr a 0100 x 10 Adr b 0200 A::x 18 x 19 y 20 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; Adr ap 0300 ? Welcher Wert welcher Speicherzelle wird durch die gleich folgenden Anweisungen links verändert ? Auf welches Objekt (a oder b) zeigt ap ? Vom Zufall abhängig, zeigt ap entweder auf das Objekt a oder auf das Objekt b.

a b ap Adr 0100 x 10 Adr 0200 A::x 18 x 19 y 20 Adr 0300 ? A a(10); B b(20); A *ap; Adr a 0100 x 10 Adr b 0200 A::x 18 x 19 y 20 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; Adr ap 0300 ? Angenommen, ap zeigt auf b. Welchen Wert hat dann ap ?

a b ap Adr 0100 x 10 Adr 0200 A::x 18 x 19 y 20 Adr 0300 A a(10); B b(20); A *ap; Adr a 0100 x 10 Adr b 0200 A::x 18 x 19 y 20 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; Adr ap 0300 Angenommen, ap zeigt auf b. Welchen Wert hat dann ap ?

a b ap Adr 0100 x 10 Adr 0200 A::x 18 x 19 y 20 Adr 0300 0200 A a(10); B b(20); A *ap; Adr a 0100 x 10 Adr b 0200 A::x 18 x 19 y 20 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; Adr ap 0300 0200

a b ap Adr 0100 x 10 Adr 0200 A::x 18 x 19 y 20 Adr 0300 0200 A a(10); B b(20); A *ap; Adr a 0100 x 10 Adr b 0200 A::x 18 x 19 y 20 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; Adr ap 0300 0200 Auf welches x würde dann die Anweisung ap->x = 13 zugreifen ? Es gibt 2 Möglichkeiten: b.A::x oder b.B::x Da sich der Compiler schon beim Compilieren (und nicht erst während der Laufzeit) entscheiden muss, kann es nicht ...

a b ap Adr 0100 x 10 Adr 0200 A::x 18 x 19 y 20 Adr 0300 0200 A a(10); B b(20); A *ap; Adr a 0100 x 10 Adr b 0200 A::x 18 x 19 y 20 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; Adr ap 0300 0200 dieses x existiert in a und b .... 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 (frühe Bindung).

a b ap Adr 0100 x 10 Adr 0200 A::x 18 x 19 y 20 Adr 0300 0200 A a(10); B b(20); A *ap; Adr a 0100 x 10 Adr b 0200 A::x 18 x 19 y 20 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; Adr ap 0300 0200 Also wird der Wert von x im Objekt b verändert auf:

a b ap Adr 0100 x 10 Adr 0200 A::x x 19 y 20 Adr 0300 0200 A a(10); B b(20); A *ap; Adr a 0100 x 10 Adr b 0200 A::x x 19 y 20 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; Adr ap 0300 0200

a b ap Adr 0100 x 10 Adr 0200 A::x 13 x 19 y 20 Adr 0300 0200 A a(10); B b(20); A *ap; Adr a 0100 x 10 Adr b 0200 A::x 13 x 19 y 20 if(rand()%2)==1) ap = &a; else ap = &b; ap->x=13; Adr ap 0300 0200 Also: Der Typ der Zeigervariablen, hier also A, und nicht der Typ des Objekts auf den ap während der Laufzeit zeigt, hier also B, bestimmt welches Mitglied (Member) von *ap angesprochen wird.

Neue Frage

a b ap Adr 0100 x 10 hallo() Adr 0200 A::x 18 x 19 y 20 A::hallo() A a(10); B b(20); A *ap; Adr a 0100 x 10 hallo() Adr b 0200 A::x 18 x 19 y 20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 ? Welcher Wert welcher Speicherzelle wird durch die folgenden Anweisungen links verändert ? Auf welches Objekt (a oder b) zeigt ap ? aus Platzgründen: hier steht wie vorher: rand()%2 = =1 Vom Zufall abhängig, zeigt ap entweder auf das Objekt a oder auf das Objekt b.

a b ap Adr 0100 x 10 hallo() Adr 0200 A::x 18 x 19 y 20 A::hallo() A a(10); B b(20); A *ap; Adr a 0100 x 10 hallo() Adr b 0200 A::x 18 x 19 y 20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 ? Angenommen, ap zeigt auf b. Welchen Wert hat dann ap ?

a b ap Adr 0100 x 10 hallo() Adr 0200 A::x 18 x 19 y 20 A::hallo() A a(10); B b(20); A *ap; Adr a 0100 x 10 hallo() Adr b 0200 A::x 18 x 19 y 20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300

a b ap Adr 0100 x 10 hallo() Adr 0200 A::x 18 x 19 y 20 A::hallo() A a(10); B b(20); A *ap; Adr a 0100 x 10 hallo() Adr b 0200 A::x 18 x 19 y 20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 0200

a b ap Adr 0100 x 10 hallo() Adr 0200 A::x 18 x 19 y 20 A::hallo() A a(10); B b(20); A *ap; Adr a 0100 x 10 hallo() Adr b 0200 A::x 18 x 19 y 20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 0200 Auf welches hallo() würde dann die Anweisung ap->hallo() zugreifen ? Es gibt 2 Möglichkeiten: b.A::hallo() oder b.B::hallo() Da sich der Compiler schon beim Compilieren (und nicht erst während der Laufzeit) entscheiden muss, kann es nicht ...

a b ap Adr 0100 x 10 hallo() Adr 0200 A::x 18 x 19 y 20 A::hallo() A a(10); B b(20); A *ap; Adr a 0100 x 10 hallo() Adr b 0200 A::x 18 x 19 y 20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 0200 dieses hallo() existiert in a und b .... B::hallo() sein, da diese Methode (falls ap auf a zeigt) nicht zu A gehört. Dagegen existiert (egal ob ap auf a oder b zeigt) immer die Methode A::hallo(). Diesen Vorgang des Compilers nennt man early binding (frühe Bindung).

a b ap Adr 0100 x 10 hallo() Adr 0200 A::x 18 x 19 y 20 A::hallo() A a(10); B b(20); A *ap; Adr a 0100 x 10 hallo() Adr b 0200 A::x 18 x 19 y 20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 0200 Also: Der Typ der Zeigervariablen, hier also A, und nicht der Typ des Objekts auf den ap während der Laufzeit zeigt, hier also b, bestimmt welches Mitglied (Member) von *ap angesprochen wird.

Mögliche Speicherbelegung beim obigen Programm (hier nochmals das Programm)

int main(){ A a(10); B b(20); A 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); }

Annahme: 1) Die Adressen wurden willkürlich gewählt. In der 4 Annahme: 1) Die Adressen wurden willkürlich gewählt. In der 4. Spalte stehen die Werte also die Inhalte der Adressen nachdem die letzte Anweisung des Programms abgearbeitet wurde. 2) Zufallsbedingt soll der Körper des else Teils der if-Verzweigung (also ap = &b) ausgeführt werden.

Adresse Symbol besteht Inhalt 0100 a x 10 ... 0200 b A::x 13 B::x 19 y 0300 ap 0500 A::hallo() Anweisungen 0600 B::hallo()

Neue Frage

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 ?

a b ap Adr 0100 x 10 hallo() Adr 0200 A::x 18 x 19 y 20 A::hallo() A a(10); B b(20); A *ap; Adr a 0100 x 10 hallo() Adr b 0200 A::x 18 x 19 y 20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 0100 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 während der Laufzeit zeigt, also A::hallo().

a b ap Adr 0100 x 10 hallo() Adr 0200 A::x 18 x 19 y 20 A::hallo() A a(10); B b(20); A *ap; Adr a 0100 x 10 hallo() Adr b 0200 A::x 18 x 19 y 20 A::hallo() B::hallo() if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 0200 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 während der Laufzeit zeigt, also B::hallo().

Das dazugehörige Programm ist das Gleiche wie oben, nur dass die Methode hallo() bei der Deklaration den Bezeichner virtual bekommt.

Das Programm

#include "stdafx. h" #include <iostream> #include <time #include "stdafx.h" #include <iostream> #include <time.h> using namespace std;

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; }; Der Bezeichner virtual vererbt sich und muß daher nicht mehr (kann aber) in den Subklassen wiederholt werden. Durch den Bezeichner virtual wird hallo() eine virtuelle Funktion. Die Verwendung von virtual ist nur innerhalb einer Klassendeklaration zulässig.

A::A(int i){ x = i; }; void A::hallo(){ cout <<"Ich bin A und " << "x= " << x << endl; }; B::B(int i):A(i-2){ x = i-1; y = i; }; void B::hallo(){ cout << "Ich bin B" << "x=" << x << "y=" << y << endl; };

int main(){ A a(10); B b(20); A 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); }

Neue Frage

Wie wird dies technisch im Speicher realsiert ?

a b ap Adr 096 &vt_A 0100 x 10 Adr 0196 &vt_B 0200 A::x 18 x 19 y 20 A a(10); B b(20); A *ap; Adr a 096 &vt_A 0100 x 10 Adr b 0196 &vt_B 0200 A::x 18 x 19 y 20 if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 ? Adr vt_B 0600 B::hallo() Adr vt_A 0500 A::hallo() 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()

a b ap Adr 096 &vt_A 0100 x 10 Adr 0196 &vt_B 0200 A::x 18 x 19 y 20 A a(10); B b(20); A *ap; Adr a 096 &vt_A 0100 x 10 Adr b 0196 &vt_B 0200 A::x 18 x 19 y 20 if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 ? Adr vt_B 0600 B::hallo() Adr vt_A 0500 A::hallo() Angenommen, ap zeigt zufallsbedingt auf a. Welchen Wert hat dann ap ?

a b ap Adr 096 &vt_A 0100 x 10 Adr 0196 &vt_B 0200 A::x 18 x 19 y 20 A a(10); B b(20); A *ap; Adr a 096 &vt_A 0100 x 10 Adr b 0196 &vt_B 0200 A::x 18 x 19 y 20 if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 Adr vt_B 0600 B::hallo() Adr vt_A 0500 A::hallo()

a b ap Adr 096 &vt_A 0100 x 10 Adr 0196 &vt_B 0200 A::x 18 x 19 y 20 A a(10); B b(20); A *ap; Adr a 096 &vt_A 0100 x 10 Adr b 0196 &vt_B 0200 A::x 18 x 19 y 20 if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 100 Adr vt_B 0600 B::hallo() Adr vt_A 0500 A::hallo() Welche Adresse wird dann beim Aufruf von hallo() in der folgenden Anweisung angesprochen ? ap->hallo() ein ?

a b ap Adr 096 &vt_A 0100 x 10 Adr 0196 &vt_B 0200 A::x 18 x 19 y 20 A a(10); B b(20); A *ap; Adr a 096 &vt_A 0100 x 10 Adr b 0196 &vt_B 0200 A::x 18 x 19 y 20 if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 100 Adr vt_B 0600 B::hallo() Adr vt_A 0500 A::hallo() 0500 Welche Methode wird also aufgerufen ? 096 A::hallo() 0100 *(ap-4)

a b ap Adr 096 &vt_A 0100 x 10 Adr 0196 &vt_B 0200 A::x 18 x 19 y 20 A a(10); B b(20); A *ap; Adr a 096 &vt_A 0100 x 10 Adr b 0196 &vt_B 0200 A::x 18 x 19 y 20 if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 ? Adr vt_B 0600 B::hallo() Adr vt_A 0500 A::hallo() Angenommen, ap zeigt zufallsbedingt auf b. Welchen Wert hat dann ap ?

a b ap Adr 096 &vt_A 0100 x 10 Adr 0196 &vt_B 0200 A::x 18 x 19 y 20 A a(10); B b(20); A *ap; Adr a 096 &vt_A 0100 x 10 Adr b 0196 &vt_B 0200 A::x 18 x 19 y 20 if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 Adr vt_B 0600 B::hallo() Adr vt_A 0500 A::hallo()

a b ap Adr 096 &vt_A 0100 x 10 Adr 0196 &vt_B 0200 A::x 18 x 19 y 20 A a(10); B b(20); A *ap; Adr a 096 &vt_A 0100 x 10 Adr b 0196 &vt_B 0200 A::x 18 x 19 y 20 if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 200 Adr vt_B 0600 B::hallo() Adr vt_A 0500 A::hallo() Welche Adresse wird dann beim Aufruf von hallo() in der folgenden Anweisung angesprochen ? ap->hallo() ein ?

a b ap Adr 096 &vt_A 0100 x 10 Adr 0196 &vt_B 0200 A::x 18 x 19 y 20 A a(10); B b(20); A *ap; Adr a 096 &vt_A 0100 x 10 Adr b 0196 &vt_B 0200 A::x 18 x 19 y 20 if(...) ap = &a; else ap = &b; ap->hallo(); Adr ap 0300 200 Adr vt_B 0600 B::hallo() Adr vt_A 0500 A::hallo() 0600 Welche Methode wird also aufgerufen ? 0196 B::hallo() 0200 *(ap-4)

Mögliche Speicherbelegung beim obigen Programm (hier nochmals das Programm)

Annahme: 1) Die Adressen wurden willkürlich gewählt. In der 4 Annahme: 1) Die Adressen wurden willkürlich gewählt. In der 4. Spalte stehen die Werte, also die Inhalte der Adressen nachdem die letzte Anweisung des Programms abgearbeitet wurde. 2) Zufallsbedingt soll der Körper der if-Verzweigung (also ap = bp) ausgeführt werden. 3) Zwischen den Zeilen stehen platzbedingt keine (durch ... getrennten) weiteren Adressen.

Adresse Symbol besteht Inhalt 096 a &vt_A 0500 0100 x 10 0196 b &vt_B 0600 0200 A::x 13 B::x 19 y 20 0300 ap vt_A &A::hallo() 0700 vt_B &B::hallo() 0800 A::hallo() Anweisungen B::hallo()

Ist early binding (frühe Bindung) auch einfacher möglich Ist early binding (frühe Bindung) auch einfacher möglich ? (ohne Pointer)

Das (einfachere) Programm ist das Gleiche wie oben, nur dass statt dem Pointer *ap ein Objekt der Klasse A verwendet wird.

#include "stdafx. h" #include <iostream> #include <time #include "stdafx.h" #include <iostream> #include <time.h> using namespace std;

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; }; virtual virtual

A::A(int i){ x = i; }; void A::hallo(){ cout <<"Ich bin A und " << "x= " << x << endl; }; B::B(int i):A(i-2){ x = i-1; y = i; }; void B::hallo(){ cout << "Ich bin B" << "x=" << x << "y=" << y << endl; };

int main(){ A a(10); B b(20); A z(123); srand((unsigned)time(NULL)); if(rand()%2==1){ z = a; } else{ z = b; } z.x = 13; z.hallo(); return(0); }

Warum wird hier kein late Binding gemacht ?

Warum wird hier kein late Binding gemacht ?

int main(){ A a(10); B b(20); A z(123); srand((unsigned)time(NULL)); if(rand()%2==1){ z = a; } else{ z = b; } z.x = 13; z.hallo(); return(0); } Durch diese Deklaration ist das Objekt z immer vom Klassentyp A. Deshalb wird hier immer early binding gemacht, ganz egal, ob man der Methode hallo den Bezeichner virtual gegeben hat.