2008-09-18 11 views
7

Angenommen, ich den folgenden Code haben:Gibt es etwas Falsches beim Zurückgeben von konstruierten Standardwerten?

class some_class{}; 

some_class some_function() 
{ 
    return some_class(); 
} 

Dies scheint ziemlich gut zu funktionieren und erspart mir die Mühe, eine Variable, die einen Rückgabewert zu machen, nur um zu erklären haben. Aber ich glaube nicht, dass ich das in irgendeiner Art von Tutorial oder Referenz gesehen habe. Ist das eine Compiler-spezifische Sache (Visual C++)? Oder macht das etwas falsch?

Antwort

16

Nein, das ist absolut gültig. Dies wird auch effizienter sein, da der Compiler tatsächlich in der Lage ist, das Temporäre zu optimieren.

+0

In der Tat sind moderne Compiler oft in der Lage, eine benannte Variable, die zurückgegeben wird, zu opimize –

1

Dies ist absolut legal C++ und jeder Compiler sollte es akzeptieren. Was lässt dich denken, dass es etwas falsch machen könnte?

+0

Es ist nur, dass ich es nie wirklich irgendwo in meiner begrenzten Erfahrung mit C++ verwendet gesehen habe. –

+0

Fair genug. Verwenden Sie es definitiv, wenn es keinen Grund gibt, eine temporäre Variable zu verwenden, dann müssen Sie es nicht tun! –

5

Das Zurückgeben von Objekten aus einem Funktionsaufruf ist das Entwurfsmuster "Factory" und wird weitgehend verwendet.

Sie sollten jedoch vorsichtig sein, ob Sie Objekte oder Zeiger auf Objekte zurückgeben. Der erste dieser Artikel wird Sie dazu bringen, Konstruktoren/Zuweisungsoperatoren zu kopieren, was sehr schmerzhaft sein kann.

2

Es ist gültig, aber die Leistung ist möglicherweise nicht ideal, je nachdem, wie es heißt.

Zum Beispiel:

A a; 
a = fn(); 

und

A a = fn(); 

sind nicht das gleiche.

Im ersten Fall wird der Standardkonstruktor aufgerufen, und dann wird der Zuweisungsoperator aufgerufen, auf dem eine temporäre Variable erstellt werden muss.

Im zweiten Fall wird der Kopierkonstruktor verwendet.

Ein intelligent genug Compiler wird herausfinden, welche Optimierungen möglich sind. Aber wenn der Kopierkonstruktor vom Benutzer bereitgestellt wird, sehe ich nicht, wie der Compiler die temporäre Variable optimieren kann. Es muss den Kopierkonstruktor aufrufen, und dazu muss es eine andere Instanz haben.

+1

Der Standard erlaubt dem Compiler ausdrücklich, den Kopierkonstruktor zu verlassen. –

1

Das ist der beste Weg, es zu tun, wenn Ihre Klasse ziemlich leicht ist - ich meine, dass es nicht sehr teuer ist, eine Kopie davon zu machen.

Ein Nebeneffekt dieser Methode ist jedoch, dass es eher dazu führt, dass temporäre Objekte erstellt werden, obwohl das davon abhängen kann, wie gut der Compiler die Dinge optimieren kann.

Für schwerere Klassen, die nicht kopiert werden sollen (zum Beispiel ein großes Bitmap-Bild), ist es eine gute Idee, solche Dinge als Referenzparameter zu übergeben, die dann ausgefüllt werden Stellen Sie unbedingt sicher, dass keine temporären Objekte erstellt werden.

Insgesamt kann es passieren, dass die Vereinfachung der Syntax und die direktere Ausführung der Dinge einen Nebeneffekt der Erstellung von mehr temporären Objekten in Ausdrücken haben, was Sie beim Entwerfen der Schnittstellen für schwerere Objekte beachten sollten.

2

Der Unterschied zwischen Rob Walker Beispiel heißt Return Value Optimization (RVO), wenn Sie dafür googeln möchten.

Wenn Sie möchten, dass Ihr Objekt am effizientesten zurückgegeben wird, erstellen Sie das Objekt auf dem Heap (dh über new) mit einem shared_ptr und geben Sie stattdessen shared_ptr zurück. Der Zeiger wird zurückgegeben und die Referenz zählt korrekt.

+1

Im Allgemeinen ist RVO effizienter als die Verwendung von shared_ptr, das Objekt wird auf dem Heap erstellt. Außerdem muss shared_ptr ein zusätzliches Objekt zum Speichern der Anzahl erstellen. –