Frage

Ich las Kopieren und Tauschen .

Ich habe versucht, ein paar Links auf Copy Elision lesen kann aber nicht herausfinden, richtig, was es bedeutet. Kann jemand bitte erklären, was diese Optimierung ist, und vor allem, was mit dem folgenden Text Mittelwert

  

Dies ist nicht nur eine Frage der Bequemlichkeit, sondern in der Tat einer Optimierung. Wenn der Parameter (e) bindet an einen L-Wert (ein anderes nicht-const Objekts), eine Kopie des Objekts erfolgt automatisch während der Parameter zu schaffen (s). Wenn jedoch s bindet an einen R-Wert (temporäres Objekt, wörtliches), wird die Kopie der Regel elided, die einen Anruf an einen Kopierkonstruktor und Destruktor speichert. In der früheren Version des Zuweisungsoperators, wo der Parameter als konstante Referenz angenommen wird, kopieren elision nicht geschieht, wenn die Referenz bindet an einem R-Wert. Dies führt zu einem zusätzlichen Objekt erzeugt und zerstört werden.

War es hilfreich?

Lösung

Das Copy-Konstruktor existiert Kopien zu erstellen. In der Theorie, wenn Sie schreiben eine Zeile wie:

CLASS c(foo());

Der Compiler würde den Copy-Konstruktor ruft die Rückkehr von foo() in c zu kopieren.

Kopieren elision ist eine Technik, die Copykonstruktor überspringen aufrufen, um nicht zu zahlen für die Overhead.

Zum Beispiel kann der Compiler, dass foo() arrangiert direkt den Rückgabewert in c konstruieren.

Hier ist ein weiteres Beispiel. Angenommen, Sie haben eine Funktion:

void doit(CLASS c);

Wenn Sie es mit einem tatsächlichen Argumente nennen, hat die Compiler den Kopierkonstruktor aufgerufen, so dass die ursprünglichen Parameter nicht geändert werden können:

CLASS c1;
doit(c1);

Aber jetzt ein anderes Beispiel betrachten, sagen wir, Sie rufen Sie Ihre Funktion wie folgt aus:

doit(c1 + c1);

operator+ ist zu haben, ein temporäres Objekt (ein R-Wert) zu erstellen. Anstatt die Copykonstruktor Aufruf vor doit() Aufruf kann der Compiler die temporäre übergeben, die von operator+ geschaffen wurden, und dass stattdessen doit() passieren.

Andere Tipps

Hier ist ein Beispiel:

#include <vector>
#include <climits>

class BigCounter {
 public:
   BigCounter &operator =(BigCounter b) {
      swap(b);
      return *this;
   }

   BigCounter next() const;

   void swap(BigCounter &b) {
      vals_.swap(b);
   }

 private:
   typedef ::std::vector<unsigned int> valvec_t;
   valvec_t vals_;
};

BigCounter BigCounter::next() const
{
   BigCounter newcounter(*this);
   unsigned int carry = 1;
   for (valvec_t::iterator i = newcounter.vals_.begin();
        carry > 0 && i != newcounter.vals_.end();
        ++i)
   {
      if (*i <= (UINT_MAX - carry)) {
         *i += carry;
      } else {
         *i += carry;
         carry = 1;
      }
   }
   if (carry > 0) {
      newcounter.vals_.push_back(carry);
   }
   return newcounter;
}

void someFunction()
{
    BigCounter loopcount;
    while (true) {
       loopcount = loopcount.next();
    }
}

In somefunction die Linie loopcount = loopcount.next(); Vorteile stark von Kopie elision. Wenn Kopie elision nicht erlaubt war, würde erfordern, dass Zeile 3 Anrufungen des Copykonstruktor und einem zugehörigen Anruf zu einem destructor. Mit Kopie elision erlaubt wird, kann es auf 1 Aufruf des Copykonstruktor reduziert werden, die explizit einen innerhalb von BigCount::next() wo newcounter deklariert wird.

Wenn operator = wie dies erklärt und definiert worden:

BigCounter &BigCounter::operator =(const BigCounter &b) {
   BigCounter tmp(b);
   swap(tmp);
   return *this;
}

Es hätte hatte 2 Anrufungen des Copykonstruktor haben, auch mit Kopie elision. Ein bis Konstrukt newcounter und das andere Konstrukt tmp. Und ohne Kopie elision es wäre noch 3. Aus diesem Grunde erklärt operator = so ihr Argument die Kopie Konstrukt erfordert Aufruf kann eine Optimierung sein, wenn das Funktion ‚Kopieren und Swap‘ Idiom für den Zuweisungsoperator. Wenn der Copykonstruktor zum Aufbau eines Argument aufgerufen wird, kann seine Anrufung elided werden, aber wenn es aufgerufen wird eine lokale Variable zu erstellen, kann es nicht sein.

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