OOP Fragen
-
hi
Brauch DRINGEND (!!!) ein paar Antworten.
Die Fragen sind vom Prof und stehen in Anführungszeichen..."Was muß bei der Definition der Klasse STRING beachtet werden, wenn im Programm folgende Vereinbarung
möglich sein soll:
STRING stringField[10];"
Man kann doch aber arrays von Objekten erzeugen. Was muss da beachtet werden?"Warum können die Funktionsdefinitionen für eine Template-Klasse nicht getrennt übersetzt werden?"
???"Was kann ein Exception-Handler tun, wenn er eine gefangene Ausnahme nicht vollständig behandeln kann?"
Ich dachte ein Exception-Handler kann eine Ausnahme nur ganz oder gar nicht behandeln."Gegeben seien die beiden Klassen A und B, wobei B von A abgeleitet sei (A ist Basisklasse). In beiden Klassen
ist die virtuelle Funktion f1 definiert. Gegeben seien weiterhin folgende Definitionen:
A a, *pa = &a;
B b, *pb = &b;
A *pab = new B;
Geben Sie hinter jeder der folgenden Anweisungen an, ob A::f1 oder B::f1 aufgerufen wird, und ob späte Bindung erfolgt:
a.f1(); //A::f1 frühe Bindung
b.f1(); //B::f1 frühe Bindung
pa->f1(); //A::f1 frühe Bindung ???
pb->f1(); //B::f1 frühe Bindung ???
pab->f1();//B::f1 späte Bindung"Bei den Fragezeichen. Die Zeiger pa und pb sind doch statisch, da sie auf vorkompilierte Objekte a und b verweisen. Ist das dann nicht frühe Bindung? Oder doch späte?
Bitte um schnelle Hilfe

-
opengl_noob schrieb:
"Was muß bei der Definition der Klasse STRING beachtet werden, wenn im Programm folgende Vereinbarung
möglich sein soll:
STRING stringField[10];"
Man kann doch aber arrays von Objekten erzeugen. Was muss da beachtet werden?Ja, man kann, allerdings nicht mit beliebigen Objekten. Damit das funktioniert, braucht die Klasse einen Default-Ctor.
"Warum können die Funktionsdefinitionen für eine Template-Klasse nicht getrennt übersetzt werden?"
???Weil der Compiler die Funktionsdefinition UND die Instanziierung an einem Platz haben will, um etwas produktives fabrizieren zu können (ja, es gibt "export", aber das unterstützt immer noch fast niemand).
"Was kann ein Exception-Handler tun, wenn er eine gefangene Ausnahme nicht vollständig behandeln kann?"
Ich dachte ein Exception-Handler kann eine Ausnahme nur ganz oder gar nicht behandeln.Nein, er kann die Ausnahme auch kurz ansehen und dann weitergeben (throw;)
"Gegeben seien die beiden Klassen A und B, wobei B von A abgeleitet sei (A ist Basisklasse). In beiden Klassen
ist die virtuelle Funktion f1 definiert. Gegeben seien weiterhin folgende Definitionen:
A a, *pa = &a;
B b, *pb = &b;
A *pab = new B;
Geben Sie hinter jeder der folgenden Anweisungen an, ob A::f1 oder B::f1 aufgerufen wird, und ob späte Bindung erfolgt:
a.f1(); //A::f1 frühe Bindung
b.f1(); //B::f1 frühe Bindung
pa->f1(); //A::f1 frühe Bindung ???
pb->f1(); //B::f1 frühe Bindung ???
pab->f1();//B::f1 späte Bindung"Bei den Fragezeichen. Die Zeiger pa und pb sind doch statisch, da sie auf vorkompilierte Objekte a und b verweisen. Ist das dann nicht frühe Bindung? Oder doch späte?
Das müsste späte Bindung sein - schließlich kann der Compiler nicht feststellen, ob zwischen den Definitionen und den Aufrufen noch ein "pa=pb;" stattgefunden hat.
-
Was ist denn eine frühe und was eine späte Bindung?
"Gegeben seien die beiden Klassen A und B, wobei B von A abgeleitet sei (A ist Basisklasse). In beiden Klassen
ist die virtuelle Funktion f1 definiert. Gegeben seien weiterhin folgende Definitionen:
A a, *pa = &a;
B b, *pb = &b;
A *pab = new B;
AUFGABE: Geben Sie hinter jeder der folgenden Anweisungen an, ob A::f1 oder B::f1 aufgerufen wird, und ob späte Bindung erfolgt!
a.f1();
b.f1();
pa->f1();
pb->f1();
pab->f1();class a { public: virtual void f1() { std::cout << "a" << std::endl; } }; class b : public a { public: virtual void f1() { std::cout << "b" << std::endl; } };...
a a_inst; // Erzeugen eines a-Objektes auf dem Stack a* a_ptr = &a_inst; // Zeiger auf a-Objekt a_inst auf dem Stack b b_inst; // Erzeugen eines b-Objektes auf dem Stack b* b_ptr = &b_inst; // Zeiger auf b-Objekt b_inst auf dem Stack a* base_ptr = new b; // Erzeugen eines b-Objektes auf dem HeapSo das ist der Unterschied zwischen den einzellnen Sachen. Wo ist da jetzt ne direkte und ne indirekte Bindung ... wasn Quark

Warum können die Funktionsdefinitionen für eine Template-Klasse nicht getrennt übersetzt werden?
Auf Deutsch: Warum müssen Templates im Header sein?
Was muß bei der Definition der Klasse STRING beachtet werden, wenn im Programm folgende Vereinbarung
möglich sein soll:
STRING stringField[10];Man kann Arrays von Objekten erzeugen. Was muss da beachtet werden?
Richtig, nichts.
-
(D)Evil schrieb:
So das ist der Unterschied zwischen den einzellnen Sachen. Wo ist da jetzt ne direkte und ne indirekte Bindung ... wasn Quark

Man kann Arrays von Objekten erzeugen. Was muss da beachtet werden?
Richtig, nichts.
Manchmal solltest Du auf den Ton achten, den Du bei Deinen (z.T. falschen) Antworten an den Tag legst :p
-
(D)Evil schrieb:
So das ist der Unterschied zwischen den einzellnen Sachen. Wo ist da jetzt ne direkte und ne indirekte Bindung ... wasn Quark

Nicht "direkte" oder "indirekte" Bindung, sondern "frühe" (der Compiler kann schon entscheiden, welches die richtige Methode ist) vs. "späte" (die tatsächlich aufgerufene Methode wird erst zur Laufzeit festgelegt.
Was muß bei der Definition der Klasse STRING beachtet werden, wenn im Programm folgende Vereinbarung
möglich sein soll:
STRING stringField[10];Man kann Arrays von Objekten erzeugen. Was muss da beachtet werden?
Richtig, nichts.
Falsch - es gibt durchaus Klassen, die sich nicht in ein Array pressen lassen

-
"Warum können die Funktionsdefinitionen für eine Template-Klasse nicht getrennt übersetzt werden?"
???Weil der Compiler die Funktionsdefinition UND die Instanziierung an einem Platz haben will, um etwas produktives fabrizieren zu können (ja, es gibt "export", aber das unterstützt immer noch fast niemand).
Hä? Bei mir geht das, wenn ich die Deklaration und Definition einer Methode in die Header-Datei und main in der cpp lasse, kompiliert er ohne Probs.
-
[quote="CStoll"]
opengl_noob schrieb:
"Was muß bei der Definition der Klasse STRING beachtet werden, wenn im Programm folgende Vereinbarung
möglich sein soll:
STRING stringField[10];"
Man kann doch aber arrays von Objekten erzeugen. Was muss da beachtet werden?Ja, man kann, allerdings nicht mit beliebigen Objekten. Damit das funktioniert, braucht die Klasse einen Default-Ctor.
Sry, versteh ich nicht. Was hat der Default-Konstruktor damit zu tun?
-
opengl_noob schrieb:
Hä? Bei mir geht das, wenn ich die Deklaration und Definition einer Methode in die Header-Datei und main in der cpp lasse, kompiliert er ohne Probs.
Du beschreibst ja auch gerade die funktionierende Methode. Deklaration und Definition im Header (sprich: nicht getrennt).
-
opengl_noob schrieb:
Hä? Bei mir geht das, wenn ich die Deklaration und Definition einer Methode in die Header-Datei und main in der cpp lasse, kompiliert er ohne Probs.
Wenn die Definitionen direkt im Header stehen, werden sie ja auch nicht getrennt übersetzt
Aber versuch' mal spaßeshalber, die Definitionen in eine eigene CPP auszulagern und dann zusammen mit der main.cpp zusammenzubringen - dein Linker wird sich bedanken.Edit:
Sry, versteh ich nicht. Was hat der Default-Konstruktor damit zu tun?
Die Array-Elemente müssen ja mit irgendeinem Wert gefüllt werden - und da der Compiler dort nicht einfach irgendwelche Müll-Daten reinkippen kann (nicht-initialisierte Variablen sind schon in C unangehm - bei kompliziert aufgebauten Objekten endet sowas tödlich) und keine anderen Vorgaben bekommt, ruft er für jedes Array-Element den Default-Ctor auf.
(wenn er keinen findet, wird das aber etwas schwierig)
-
Falsch - es gibt durchaus Klassen, die sich nicht in ein Array pressen lassen

Beispiel, Beispiel, Beispiel???
-
class X { public: X(float f); }; X x[100]; // PengWer die Meldung sehen möchte, möge das ganze schnell selbst durch einen Compiler jagen

-
Hier mal ein Beispiel.
Heisst das, wenn ich die überladenen Definitionen der Methode f irgendwo anders als in cpp wo die Instanziierung des Templates stattfindet (main) reinklatsche, meckert der Compiler?template <class Typ> class T { public: Typ i; void f(); }; void T<int>::f() { i=1; cout<<i; } void T<float>::f() { i=1.5; cout<<i; } void main() { T <float>t; t.f(); getch(); }
-
"Gegeben seien die beiden Klassen A und B, wobei B von A abgeleitet sei (A ist Basisklasse). In beiden Klassen
ist die virtuelle Funktion f1 definiert. Gegeben seien weiterhin folgende Definitionen:
A a, *pa = &a;
B b, *pb = &b;
A *pab = new B;
Geben Sie hinter jeder der folgenden Anweisungen an, ob A::f1 oder B::f1 aufgerufen wird, und ob späte Bindung erfolgt:
a.f1(); //A::f1 frühe Bindung
b.f1(); //B::f1 frühe Bindung
pa->f1(); //A::f1 frühe Bindung ???
pb->f1(); //B::f1 frühe Bindung ???
pab->f1();//B::f1 späte Bindung"Bei den Fragezeichen. Die Zeiger pa und pb sind doch statisch, da sie auf vorkompilierte Objekte a und b verweisen. Ist das dann nicht frühe Bindung? Oder doch späte?
Das müsste späte Bindung sein - schließlich kann der Compiler nicht feststellen, ob zwischen den Definitionen und den Aufrufen noch ein "pa=pb;" stattgefunden hat.[/quote]
Warum kann der Comiler das nicht feststellen? Die Zuweisung ist doch dann quasi auf dem Stack und steht zur Comile-Zeit fest.
-
In dem Fall ist das vielleicht noch machbar - im generellen Fall nicht mehr:
void foo(A*& ob1, A* ob2); int main() { A a, *pa=&a; B b, *pb=&b; foo(pa,pb);//eine winzige Ergänzung - und schon weiß der Compiler nicht mehr, worauf pa nun zeigt pa->f(); }Ansonsten: Bei den expliziten Instanziierungen hat der Compiler kein Problem - aber versuch mal, in der main() einen T<double> zu verwenden (dafür gibt es keine Spezialisierung und der Code der generellen Variante ist außer Reichweite).
PS: Es heißt übrigens immer noch "int main()"
-
opengl_noob schrieb:
Hier mal ein Beispiel.
Heisst das, wenn ich die überladenen Definitionen der Methode f ...Nur eine Kleinigkeit: In Deinem Beispiel findet keine Überladung statt sondern eine Spezialisierung. Das ist nicht dasselbe (für Ersteres gelten "Überladungsmechanismen" für Letzteres "Template-Mechanismen" ... die ziehen vorher).
Gruß,
Simon2.