Frage

Für dieses Programm

#include <iostream>
using std::cout;

struct C 
{
    C() { cout << "Default C called!\n"; }
    C(const C &rhs) { cout << "CC called!\n"; }
};

const C f()
{
    cout << "Entered f()!\n";
    return C();
}

int main()
{
    C a = f();
    C b = a;

    return 0;
}

die Ausgabe die ich bekomme, ist:

Entered f()!
Default C called!
CC called!

Da f() ist die Rückgabe nach Wert, es sollte eine temporäre zurückgeben.Als T a = x; ist T a(x);, wäre es nicht rufen Sie die copy-Konstruktor für den Bau von a, mit der temporären verabschiedet, in der als argument?

War es hilfreich?

Lösung

Da f() ist die Rückgabe nach Wert, es sollte eine temporäre zurückgeben.Als T a = x; ist T a(x);, wäre es nicht rufen Sie die copy-Konstruktor für den Bau von a, mit der temporären verabschiedet, in der als argument?

Look up Return-Wert-Optimierung.Dies ist standardmäßig aktiviert.Wenn Sie unter Windows mit MSVC 2005+, die Sie verwenden können /Od um diese zu deaktivieren und das gewünschte Ergebnis zu erhalten (oder -fno-elide-constructors auf GCC).Auch für MSVC sehen diese Artikel.

12.8 Kopieren Sie die Objekte der Klasse

15 Wenn bestimmte Kriterien erfüllt sind, wird eine - Implementierung erlaubt das weglassen der kopieren Sie den Bau von einem class-Objekt, auch wenn der copy-Konstruktor und/oder Destruktor für das Objekt haben-Seite Effekte.In solchen Fällen die Implementierung behandelt die Quelle und Ziel der ausgelassenen Kopiervorgang einfach als zwei verschiedene Arten von auf dasselbe Objekt verweisen, und die Zerstörung des Objekts tritt auf bei die später von den Zeiten, als die beiden Objekte haben zerstört worden sind, ohne die Optimierung.115 Diese elision kopieren Operationen darf man im folgenden Umständen (die kombiniert zu beseitigen mehrere Kopien):

in eine return-Anweisung in einer Funktion mit einer Klasse zurück geben, wenn der Ausdruck den Namen eines non-volatile automatische Objekt mit der demselben cv-unqualifizierten Typ wie die Funktion zurück geben, die Kopie operation verzichtet werden kann, durch konstruieren Sie die automatische Objekt direkt in der Funktion return Wert — in einen throw-Ausdruck, wenn der operand ist der name einer non-volatile automatische Objekt, das Kopiervorgang von der operand des exception-Objekt (15.1), kann auch weggelassen werden durch den Bau der automatische Objekt direkt in das exception-Objekt

— wenn Sie ein temporäres Objekt der Klasse, die hat nicht gebunden an ein Verweis (12.2) würde kopiert werden, um ein Objekt der Klasse mit demselben cv-unqualifizierten Typ, der Kopie operation verzichtet werden kann, durch konstruieren Sie das temporäre Objekt direkt in das Ziel der ausgelassen kopieren

— wenn der exception-Deklaration einer Ausnahme handler (Ziffer 15) deklariert ein Objekt des gleichen Typs (außer für Lebenslauf-Qualifikation) als Ausnahme Objekt - (15.1), der Vorgang kopieren können weggelassen werden, indem die Behandlung der Ausnahme-Erklärung als alias für das exception-Objekt, wenn die Bedeutung von das Programm wird unverändert mit Ausnahme für die Ausführung der Konstruktoren und Destruktor für das Objekt erklärt die Ausnahme-Erklärung.

Hinweis:Hervorhebung von mir

Andere Tipps

Dies ist ein Beispiel von Rückgabewert Optimierung (RVO) Funktionen, die Ihr Compiler unterstützt.

Eine Kopie Konstruktor möglicherweise nicht aufgerufen werden, wenn Sie mit dem Wert zurück.

Verwenden -fno-elide-constructors Option auf GCC ab, dass die Funktion aktivieren.

Ich glaube, es heißt Rückgabewert Optimierung .

gehe ich davon aus, wenn f() kehrt C Objekt des Objekt in dem Stapelspeicher der rufenden Methode zugeordnet ist daher keine Kopie erforderlich ist C a zu initialisieren. Das ist Ihre default C called.

C b = a

Dies führt zu einer Copykonstruktor daher Ihre CC called.

Btw, das Beispiel auf dem Wiki sieht ganz wie ähnlich wie der Code.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top