2012-04-10 13 views
0

Ich bereite mich morgen auf einen Test vor. Ich habe Probleme mit der untenstehenden C++ - Komplettlösung. Ich habe den Code ausgeführt und cout verwendet, um die Ausführung des Programms zu überprüfen. Die erste Sache, die ich bemerkte, dass das Programm den Standardkonstruktor in der Klasse "ein" für 3mal nur für das erste Objekt in Haupt aufruft. Ich bin wirklich verwirrt mit der Ausführung des Codes.Wie kann man wissen, welche Klasse bei 2 Klassen in C++ verwendet wird?

#include <iostream> 
    using namespace std; 

    class one { 
    int n; 
    int m; 
     public: 
    one() { n = 5; m = 6; cout << "one one made\n"; } 
    one(int a, int b) { 
     n = a; 
     m = b; 
     cout << "made one one\n"; 
    } 
    friend ostream &operator<<(ostream &, one); 
    }; 

    ostream &operator<<(ostream &os, one a) { 
    return os << a.n << '/' << a.m << '=' << 
    (a.n/a.m) << '\n'; 
    } 

    class two { 
    one x; 
    one y; 
     public: 
    two() { cout << "one two made\n"; } 
    two(int a, int b, int c, int d) { 
     x = one(a, b); 
     y = one(c, d); 
     cout << "made one two\n"; 
    } 
    friend ostream &operator<<(ostream &, two); 
    }; 

    ostream &operator<<(ostream &os, two a) { 
    return os << a.x << a.y; 
    } 

    int main() { 
    two t1, t2(4, 2, 8, 3); 
    cout << t1 << t2; 
    one t3(5, 10), t4; 
    cout << t3 << t4; 
    return 0; 
    } 

Ich verstehe nicht die erste Sache. Wenn der main den ersten Standardkonstruktor two t1, aufruft, warum wird er dreimal hintereinander aufgerufen, dann ruft er t2(4, 2, 8, 3); auf?

Es tut mir leid, wenn der Code zu lang ist, aber ich brauche wirklich Hilfe, um es zu verstehen.

Bitte beraten. Vielen Dank.

+0

Bitte erarbeiten Sie Ihre Frage, was Sie von diesem Code verstehen kann nicht? – SMK

+0

Es gibt eine spezifische Optimierung, die von C++ erlaubt ist, wo der Compiler in bestimmten Fällen Provisorien entfernen kann. Das macht es schwerer vorherzusagen, wie viele Konstruktoren aufgerufen werden. Es ist durchaus üblich, dass Compiler während des Debuggens zusätzliche ctor-Aufrufe hinterlassen, diese jedoch für die endgültige Version entfernen. – MSalters

Antwort

4

ich dieses Ergebnis zu erhalten, wenn ich den Code ausführen:

one one made 
one one made 
one two made 
one one made 
one one made 
made one one 
made one one 
made one two 

Dies liegt daran:

two t1; 
one one made //t1.x; parameterless 'one' constructor called by default 
one one made //t1.y; parameterless 'one' constructor called by default 
one two made //t1; parameterless 'two' constructor 

t2(4, 2, 8, 3) 
one one made //t2.x; default constructor as variable not present in initialization list 

one one made //t2.y; default constructor as variable not present in initialization list 

made one one //x = one(a, b) executed now 
made one one //y = one(c, d) executed now 
made one two //t2(int..) constructer called 

Hinweis, die zweimal im Fall von t2 aufgebaut x und y wie es ist keine Initialisierungsliste Um dies zu vermeiden, können Sie verwenden:

two(int a, int b, int c, int d): x(a,b), y(c,d) 
{ 
cout << "made one two\n"; 
} 
+0

Ok, nur um dies zu verdeutlichen. Also, weil es den Standardkonstruktor in "Eins" für x und y aufrufen muss und seinen eigenen Standardkonstruktor in "zwei" aufrufen muss, weshalb ich für t1 Objekt zweimal in "eins" und einmal in "zwei ", Recht? – Jack

+1

Ja. Sobald Sie ein Objekt mit "zwei" erstellen, werden alle seine Mitgliedsvariablen standardmäßig erstellt (in diesem Fall x und y). Danach wird der Körper des Konstruktors ausgeführt: "cout <<" eins zwei gemacht \ n ";" Jetzt ist die Konstruktion von t1 abgeschlossen. – vid

2

Sie werden sehen, dass die Konstruktoren der Klasse "eins" und der Klasse "zwei" dreimal vorkommen, weil drei Instanzen beider Objekte erzeugt werden.

Wenn Sie sich die Insert-Freundesfunktion genau ansehen, werden die Klassen eins und zwei sowohl nach Wert als auch nach Referenz übergeben. Eine temporäre Instanz muss mit dem Standardkopiekonstruktor erstellt werden (den Sie nicht implementiert haben).

friend ostream &operator<<(ostream &, one &obj); 
friend ostream &operator<<(ostream &, two &obj); 

und wie ich weiter suchen, zwei hat zwei Membervariablen des Typs ein, so werden Sie sehen, noch mehr Konstrukteurs Ich stelle dar: Wenn Sie weg mit den zusätzlichen Instanziierung tun wollen, Ihre Inserter Funktionen dies ändern .

und schließlich sollten Testklassen wie diese foo und bar genannt werden. ein und zwei sind schwer zu kommunizieren, selbst zu sich selbst. (Imho)

+0

Danke. Ich sehe, was Sie sagen, aber dieser Code wird vom Lehrer zur Verfügung gestellt. – Jack

+0

ok, aber warum, wenn es zwei t1 heißt, nennen wir nicht die beiden Standardkonstruktoren? – Jack

+1

Ich vermute, wenn Sie den Code in einem Debugger durchlaufen würden, würden Sie sehen, dass die beiden Konstruktoren _are_ aufgerufen werden.Ich benutze meinen Gehirn-Debugger hier im Moment aber so bin ich nur so sicher. :) –

1

Vom ersten Objekt in main.Two Standardkonstruktoren von „Eins“ genannt, weil Klasse „zwei“ hat zwei Objekte der Klasse „Eins“ und einen Standard-Konstruktor aufgerufen von "Zwei" als normal.

1

ist hier, dass die Ausgabe, die ich sehe:

one one made
one one made
one two made
one one made
one one made
made one one
made one one
made one two
5/6=0
5/6=0
4/2=2
8/3=2
made one one
one one made
5/10=0
5/6=0

Und es Sinn für mich. Ich sehe nicht den Standardkonstruktor von einem, der für das erste Objekt 3mal angerufen wird.

Was den Ausgang geht, hier, was passiert:

two t1, t2(4, 2, 8, 3);

Für t1, ruft es Standardkonstruktors von einem, sowohl für die Objekte, die in der Klasse definiert sind

two (one x and one y)

so ausgegeben wird "one one made" und "one one made" nächsten es führt den Standardkonstruktor von zwei so die Ausgang ist "eins zwei made" nächste für t2, ruft wieder Standardkonstruktors einer für beide x und y so ist der Ausgang "one man aus" und "ein einer gemacht" nächsten führt sie

x = one(a,b) and y =one(c,d)

so jetzt druckt es "made man ein" und "aus einer one" jetzt im Konstruktor von zwei() wie wir "gemacht eins zwei" die gleiche gedruckt wird ...

cout << t1 << t2; 

one t3(5, 10), t4; 

Für diese Aussage wieder, für t3, ruft er den Konstruktor von eins und druckt "gemacht o ne Eins“ Und für t4 führt er den Standard-Konstruktor und druckt‚ein eins gemacht‘

cout << t3 << t4; 
Verwandte Themen