410 Stimmen

Ist die Praxis, eine C++-Referenzvariable zurückzugeben, schlecht?

Dies ist meiner Meinung nach etwas subjektiv; ich bin mir nicht sicher, ob die Meinung einhellig ist (ich habe viele Codeschnipsel gesehen, in denen Referenzen zurückgegeben werden).

Laut einem Kommentar gegenüber die Frage, die ich gerade gestellt habe, bezüglich der Initialisierung von Referenzen Die Rückgabe eines Verweises kann böse sein, weil es [so wie ich es verstehe] leichter ist, das Löschen zu verpassen, was zu Speicherlecks führen kann.

Das beunruhigt mich, denn ich bin den Beispielen gefolgt (es sei denn, ich bilde mir etwas ein) und habe dies an mehreren Stellen getan... Habe ich das falsch verstanden? Ist es böse? Wenn ja, wie böse?

Ich fühle, dass wegen meiner gemischten Tasche von Zeigern und Referenzen, kombiniert mit der Tatsache, dass ich neu in C++ bin, und insgesamt Verwirrung über was zu verwenden, wenn, meine Anwendungen müssen Speicherleck Hölle sein ...

Ich verstehe auch, dass die Verwendung von intelligenten/gemeinsamen Zeigern allgemein als der beste Weg zur Vermeidung von Speicherlecks akzeptiert wird.

11voto

John Dibling Punkte 96619

"Die Rückgabe eines Verweises ist schlecht, weil, einfach [so wie ich es verstehe], es macht es es einfacher macht, das Löschen zu verpassen"

Das stimmt nicht. Die Rückgabe einer Referenz impliziert nicht die Semantik des Besitzes. Das heißt, nur weil Sie dies tun:

Value& v = thing->getTheValue();

...bedeutet nicht, dass Sie jetzt Eigentümer des mit v bezeichneten Speichers sind;

Dies ist jedoch ein furchtbarer Code:

int& getTheValue()
{
   return *new int;
}

Wenn Sie so etwas tun, weil "Sie benötigen keinen Zeiger auf diese Instanz" dann: 1) Dereferenzieren Sie einfach den Zeiger, wenn Sie einen Verweis benötigen, und 2) benötigen Sie schließlich den Zeiger, da Sie ein new mit einem delete abgleichen müssen, und Sie benötigen einen Zeiger, um delete aufzurufen.

8voto

Es gibt zwei Fälle:

  • const-Referenz - gute Idee, manchmal, besonders für schwere Objekte oder Proxy-Klassen, Compiler-Optimierung

  • Nicht-Konst-Referenz - schlechte Idee, bricht manchmal Kapselungen

Beide haben dasselbe Problem - können möglicherweise auf ein zerstörtes Objekt verweisen...

Ich würde empfehlen, intelligente Zeiger für viele Situationen zu verwenden, in denen Sie einen Verweis/Zeiger zurückgeben müssen.

Beachten Sie auch Folgendes:

Es gibt eine formale Regel - der C++-Standard (Abschnitt 13.3.3.1.4, falls Sie daran interessiert sind) besagt, dass ein temporäres Element nur an eine const-Referenz gebunden werden kann - wenn Sie versuchen, eine nicht-konst-Referenz zu verwenden, muss der Compiler dies als Fehler anzeigen.

5voto

Sie ist nicht nur nicht böse, sondern manchmal sogar unerlässlich. Beispielsweise wäre es unmöglich, den []-Operator von std::vector zu implementieren, ohne einen Referenzrückgabewert zu verwenden.

2voto

AMA Punkte 3928

Zusatz zur akzeptierten Antwort:

struct immutableint {
    immutableint(int i) : i_(i) {}

    const int& get() const { return i_; }
private:
    int i_;
};

Ich würde sagen, dieses Beispiel ist nicht in Ordnung und sollte nach Möglichkeit vermieden werden. Warum? Es ist sehr einfach, mit einem hängender Verweis .

Um dies an einem Beispiel zu verdeutlichen:

struct Foo
{
    Foo(int i = 42) : boo_(i) {}
    immutableint boo()
    {
        return boo_;
    }  
private:
    immutableint boo_;
};

Eintritt in die Gefahrenzone:

Foo foo;
const int& dangling = foo.boo().get(); // dangling reference!

1voto

MinandLucy Punkte 46

Die Rückgabereferenz wird in der Regel bei der Überladung von Operatoren in C++ für große Objekte verwendet, da die Rückgabe eines Wertes eine Kopieroperation erfordert (bei der Überladung von Operatoren wird normalerweise kein Zeiger als Rückgabewert verwendet).

Der Rückgabeverweis kann jedoch zu Problemen bei der Speicherzuweisung führen. Da ein Verweis auf das Ergebnis aus der Funktion als Verweis auf den Rückgabewert übergeben wird, kann der Rückgabewert keine automatische Variable sein.

Wenn Sie eine zurückkehrende Referenz verwenden möchten, können Sie einen Puffer eines statischen Objekts verwenden. zum Beispiel

const max_tmp=5; 
Obj& get_tmp()
{
 static int buf=0;
 static Obj Buf[max_tmp];
  if(buf==max_tmp) buf=0;
  return Buf[buf++];
}
Obj& operator+(const Obj& o1, const Obj& o1)
{
 Obj& res=get_tmp();
 // +operation
  return res;
 }

auf diese Weise können Sie die Rückverweisung sicher verwenden.

Aber Sie könnten immer Zeiger anstelle von Verweis für die Rückgabe Wert in functiong verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X