Frage

Ich habe nicht das Gefühl, (noch, ich hoffe), für, ob der Wert oder Referenzsemantik in einigen Situationen zu wählen. Gibt es eine Faustregel gilt: I anwenden kann?

Ich nehme in der Regel Referenzen für alles andere als die eingebauten Datentypen (char, int, bool, double etc.). Aber manchmal ist es nicht möglich, Referenzen aus einer Funktion zurückzukehren, so dass ich zu verwenden Zeiger haben würde. Die folgende Funktion ist ein Beispiel dafür:

Foo bar()
{
    Foo f;
    f.do_stuff();
    return f;
}

würde ich boost :: shared_ptr das Foo-Objekt zu speichern, aber es macht mit dem Objekt arbeitet ziemlich hässlich. Ich suche zur Zeit an einer Funktion, dass die Renditen einen deque, die kaum mehr als 10 Elemente haben (das ist, was ich nehme an, ich habe keine Möglichkeit, sicher zu machen). Wäre es OK sein, dies von Wert zurückgeben? Sind meine Überlegungen ein Fall der vorzeitigen Optimierung?

War es hilfreich?

Lösung

nach Wert zurückkehrend ist in Ordnung, da die meisten Compiler die zusätzliche Kopie optimieren weg (die Rückgabewert-Optimierung genannt wird, oder besser gesagt, in Ihrem Fall Rückgabewert Optimierung Named).

Aber der idiomatische Weg ist

void bar(Foo& out)
{
   out.do_stuff();
}

Andere Tipps

Auf jedem Fall nicht zurück alles auf dem Stapel reserviert (das heißt lokales Variable, wie f hier) durch Verweis oder Zeiger.

Sie können dies immer tun:

Foo& bar(Foo& f)
{
    f.do_stuff();
    return f;
}

Und es wie folgt verwendet werden:

Foo f;
bar(f);

Der Nachteil hierbei ist, dass Sie nicht, dass bar() garantieren können, eine neue Kopie eines Foo Objekt erhalten. Wenn das wichtig ist, werden Sie es auf diese ändern müssen:

Foo& bar(Foo& f)
{
    f = Foo();
    f.do_stuff();
    return f;
}

Aber dann wird es eine unnötige Initialisierung, wenn es eine neue Kopie bekommt. Alternativ können Sie einfach f vor doSomething() untersuchen und eine Ausnahme auslösen, wenn es nicht den Erwartungen ist.

Verwenden Sie eine Referenz, wenn Sie den Status einer Variablen oder Objekt beibehalten werden soll (dh die gleiche Variable an den rufenden Routine reurning nach einigen procesisng auf die Variable / Objekt durch die aufgerufene Routine getan wurde) und auch im Falle des Führens große Daten an die Funktion sonst wird es doppelte Kopie der großen volumed Daten sein.

Auch in einigen wo weisee Bedürfnisse von Objekten Kopieren Bit verhindert werden, in solchen Fällen machen wir die Kopie Konstruktor einer Klasse als privat.

Meine normalen Regeln sind:

  1. immer Pass von Wert verwenden.

    Einfach, nicht wahr? Referenz saugen. Sie sollten nie eingeführt worden sind.

  2. Wenn Sie einen „Wert wie Datenstruktur“ haben es passieren. Wenn Sie ein „Objekt wie Datenstruktur“ haben übergeben Sie einen Zeiger (Referenzsemantik, übergeben Sie den Wert).

    Es ist in der Regel klar, welche Art von Sache, die ein Typ ist: Wert oder Objekt. Wenn Sie es mutieren können, sein Objekt.

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