Das ist zwar nicht gerade falsch, aber keine gute Idee.
MyClass& doSomething() {
return *(new MyClass());
}
Nach Ihrer Rückkehr niemand hat den ursprünglichen Zeiger, so wird niemand jemals delete
es. * Es ist also ein Speicherleck.
Sie sollten eigentlich nie eine new
schreiben, es sei denn, Sie haben eine entsprechende delete
-oder, besser, ein intelligenter Zeiger Konstruktor.
Inzwischen diese Zeile in Ihrem ursprünglichen Code:
MyClass a = doSomething();
... wird eine Kopie des Wertes ohnehin machen. Angenommen, es handelt sich nicht um einen weiteren Fehler, der behoben werden muss, warum sollten Sie ein Objekt heap-allokieren und einen Verweis zum Kopieren und Lecken zurückgeben? Einfach das ausge Objekt nach Wert:
MyClass doSomething() {
return MyClass();
}
Jetzt müssen Sie sich nicht über das Löschen nichts kümmern, weil Sie nie etwas auf dem Heap erstellt.
Best Practices können in der Regel in den vier Buchstaben RAII zusammengefasst werden: Ressourcen Acquisition Initialisierung ist. (Und die logische Folge, dass Zerstörung ist Release.) Wenn Sie etwas haben, das unmöglich oder teuer ist, um Wert zu übergeben, dann übergeben Sie einen Griff nach Wert. Zum Beispiel:
unique_ptr<MyClass> doSomething() {
return unique_ptr<MyClass>(new myClass());
}
unique_ptr<MyClass> a = doSomething();
Jetzt ist es nur ein Zeiger, der herum kopiert wird. Das Objekt selbst wird innerhalb von doSomething
erstellt und gelöscht, sobald a
den Gültigkeitsbereich verlässt (oder, wenn Sie es an eine andere Variable übergeben, immer wenn , dass den Geltungsbereich verlässt, usw.).
Auf der anderen Seite, wenn MyClass
ist nur eine Handvoll leicht kopierbar Werte **, kopieren Sie es einfach.
* Es ist nicht unmöglich jemals löschen; Sie können immer einen Zeiger auf die Referenz und delete
das nehmen. Es ist sehr unwahrscheinlich, dass Sie das jemals tun werden, und es wird peinlich aussehen. Wenn Sie Zeiger weitergeben möchten, übergeben Sie Zeiger. Wenn Sie keine Zeiger weitergeben möchten, müssen Sie Besitz in einer Klasse einschließen und die Klasse nach Wert übergeben.
** Mit "leicht kopierbar" meine ich, dass es einfach ist, sie sicher zu kopieren, und dass Sie tatsächlich so tun. Ein roher Pointer oder ein Datei-Handle sind zum Beispiel nur ein paar Bytes, und der Standard-Copy-Konstruktor kopiert sie gerne für Sie ... aber dann haben Sie mehrere Verweise auf dasselbe Heap-Objekt oder dieselbe Heap-Datei, und es ist unmöglich, sie zu verfolgen wer ist verantwortlich für das Löschen oder Schließen.
Kein const notwendig, erste Option ist gut. Sie können auch einen Zeiger zurückgeben, wenn Sie möchten. Wie du willst. –
Aber die Referenz wurde vom Anrufer nicht zugewiesen. Es wurde während des Aufrufs instanziiert ... also dachte ich mir, wenn du nicht neu verwendest, würde es den Gültigkeitsbereich verlassen, weil es auf dem Stapel statt auf dem Haufen wäre. –
@BrianCain Er braucht unbedingt 'new', weil sonst das Objekt zerstört wird, sobald' doSomething() 'beendet ist. –