2016-08-10 5 views
0

Sagen wir, ich habe ein ObjektWelcher Konstruktor wird in diesem Fall aufgerufen?

class A { 
    public: 
    int bar(); 
}; 

A foo() {return A();} 
int A::bar() {return 5;} 

Und ich tue dies dann:

int i = foo().bar(); 

Welche Konstruktor für den temporären Wert, wenn foo() kehrt erstellt aufgerufen wird?

+3

Die Frage kann einfach auf 'A foo() {return A(); } ', keiner der übrigen ist relevant. Und dann ... welcher Konstrukteur denkst du? Es ist einfach zu instrumentieren und herauszufinden. Fragen Sie die Ergebnisse, die Sie bekommen haben? – Barry

+0

@Barry nicht unbedingt leicht zu testen, wegen der Kopie Elision –

+0

Wie ich herausgefunden habe - mein Problem wurde durch Kopie elision verursacht. –

Antwort

1

Der Code ist:

A foo() {return A();} 

Wenn foo() genannt wird, die Reihenfolge der Effekte ist:

  1. Temporary von A() erstellt A ‚s Standard-Konstruktor verwenden.
  2. Rückgabewertobjekt vom Typ A, das mit dem Konstruktor copy/move erstellt wurde, mit dem temporären Argument von Schritt 1 (dh Konstruktor verschieben, falls vorhanden, andernfalls Konstruktor kopieren).
  3. Temporär von Schritt 1 wird zerstört.

Dies ist jedoch ein copy elision Kontext, so dass die Compiler alle 3 Stufen in eine kombinieren könnten, und erstellen Sie das Rückgabewert Objekt mit A ‚s Standard-Konstruktor.

Was mit dem Rückgabewertobjekt passiert, hängt davon ab, was der aufrufende Code tut. Es könnte weitere Kopie Elision geben. In der Verwendung:

int i = foo().bar(); 

nichts anderes passiert; bar() wird am Rückgabewertobjekt aufgerufen, der Wert wird i zugewiesen, und dann wird das Rückgabewertobjekt zerstört.

0

Wenn Sie mit C++ 11 kompilieren, innerhalb foo, wenn return A() ausgeführt wird, ruft es Standardkonstruktor auf. Dann, wenn es von foo zurückkommt, wird move constructor aufgerufen. Aber wenn Sie mit älteren Versionen kompilieren, wird der erste Standardkonstruktor aufgerufen, dann wird der Kopierkonstruktor aufgerufen.

0

Der Standardkonstruktor wird aufgerufen. Vielleicht macht es das genauer:

#include <iostream> 

using namespace std; 

class A { 
public: 
    A() { 
    cout << "A's default ctor" << endl; 
    } 
}; 

int main() { 
    A a; 
    return 0; 
} 
Verwandte Themen