2010-12-27 8 views
3

Das Prüfprogramm istWarum weder Konstruktor noch Zuweisungsoperator beim Deklarieren eines Objekts ausgeführt?

#include <iostream> 
using namespace std; 

class A 
    {public: 
     A(): I(0) {cout << "default construcot" << endl; }; 
     explicit A (int i): I(i) {cout << "another construcot" << endl; }; 
     A (const A& a): I(a.I) {cout << "copy constructor" << endl; } 
     A& operator = (const A& a) 
      {cout << "assignment operator" << endl; 
      if (this == &a) return *this; 
      I = a.I; 
      return *this; 
      } 
     void show() {cout << I << endl; }; 
    private: 
     int I; 
    }; 

int main() 
    {A a = A(1); 
    A b; 
    b = A(2); 
    a.show(); 
    b.show(); 
    return 0; 
    } 

der Ausgang

another construcot 
default construcot 
another construcot 
assignment operator 
1 
2 

zeigt, daß das Objekt 'a' im Gegensatz zu 'B' von A konstruiert wurde (1) "direkt" ohne Ausführung von Zuweisungsoperator. Aber der Kopierkonstruktor wurde nicht ausgeführt. Warum? Gibt es eine Möglichkeit, die Ausführung des Zuweisungsoperators in diesem Fall zu erzwingen? Ich würde ein solches Verhalten erwarten, wenn ich

schrieb
A a (1); 

aber ich will

A a = A(1); 

, die von dem ersten Fall unterscheidet sich haben. Oder nicht?

(In der Tat scheint das Problem, wenn ich eine Klasse B von A abgeleitet und will A den Zuweisungsoperator Erklärung wie A a = B (...) zu handhaben.)

+0

Der Compiler-Schreiber war schlau genug, unnötige Aufrufe von Zuweisungsoperator/Kopierkonstruktor zu vermeiden. – DumbCoder

+0

Warum interessieren Sie sich für die Zuordnung zu selbst? Wenn (dies == & a) 'die Klasse ist so einfach, dass es keine Rolle spielt. Wenn es komplexer war, dann sollten Sie das Kopieren und Tauschen von Idium verwenden, und dann wird der Test sowieso überflüssig. –

Antwort

3

Warum

Der Standard der Compiler die Kopie Konstruktion zu optimieren, entfernt werden können. Nicht das ist NICHT eine Zuordnung, wie es Teil der Deklaration ist (also wenn die Optimierung nicht durchgeführt wurde, würde es in einem temporären Objekt und dann eine Kopie Konstruktion der temporäre in a).

Gibt es eine Möglichkeit, die Ausführung des Zuweisungsoperators in diesem Fall zu erzwingen.

Das hängt von Ihrem Compiler ab. Aber ich weiß nichts von dem, was es dir erlauben würde, dies zu erzwingen (aber dann habe ich nie versucht, es auszuschalten). Versuchen Sie, alle Optimierungen Ihres Compilers zu deaktivieren.

Ich hätte ein solches Verhalten erwartet, wenn ich schrieb: A a (1);

Der Standard besagt ausdrücklich, dass Ihre Version in diese optimiert werden kann.

Ich habe eine Klasse B von A abgeleitet und soll eine der Zuweisungsoperator Erklärung wie A a = B (...).)

zu behandeln, wenn Sie tun, dass Sie das B schneiden wird und Ordnen Sie einfach den A-Teil des B-Objekts zu.
Möchten Sie eine Referenz verwenden?

A const& a = B(); 
+0

Nun, ich verstehe ... Ich könnte Referenz oder sogar Zeiger verwenden, aber ... lassen Sie uns glauben, dass jemand meine Klasse benutzen wird und von ihm "normales" Verhalten erwartet. Vielleicht versuche ich alles falsch zu machen, wahrscheinlich werde ich in Zukunft einen Ratschlag geben. – Nick

1

Warum? Weil der Compiler dazu ziemlich frei ist und die meisten es tun.

Können Sie es erzwingen? No.

6

Diese

A a = A(1); 

ist nicht äquivalent dazu:

A a; 
a = A(1); 

Im zweiten Fall = ein Operator ist, im ersten Fall = ist kein Operator. In der ersten Anweisung ist es eine Initialisierungssyntax. Der Compiler kann kopieren Konstruktor, aber es kann es optimieren, da es einer der Orte ist, wo es von der Sprache erlaubt ist (RVO, Exception Throw, etc ...).

1

Es ist explizit in der Sprache definiert, dass der Compiler die Copy-Konstruktionen grundsätzlich entfernen kann, wann immer es will, und die erste Form ist sowieso Initialisierungssyntax. Sie werden jedoch wahrscheinlich feststellen, dass dieses Verhalten für den Fall entfernt wird, dass Sie es mit einer tatsächlich abgeleiteten Instanz aufrufen, da dies die Korrektheit Ihres Programms beeinträchtigen würde.

1

Ich hoffe A a(1); und A a = 1; ist streng das gleiche, es durch Standard garantiert.