HOWTO · C++

Kopieren Sie ein Vektor-Container-Objekt in C++

In diesem Artikel wird das Kopieren eines Vektorcontainerobjekts in C++ veranschaulicht.

Auf dieser Seite

Um einen C++-std::vector zu kopieren, verwenden Sie beim Erstellen eines neuen Vektors den Copy-Konstruktor und beim Ersetzen des Inhalts eines bestehenden Vektors den Copy-Zuweisungsoperator. Für einen ausgewählten Bereich eignet sich der Bereichskonstruktor. std::copy funktioniert, wenn im Zielbereich bereits genügend Platz vorhanden ist; mit std::back_inserter können Sie Elemente an einen Zielvektor anhängen. Diese Operationen kopieren Elemente entsprechend ihrem Typ; Objekte, auf die Zeiger verweisen, werden dabei nicht rekursiv kopiert.

Einen Vektor mit Copy-Konstruktor oder Zuweisungsoperator kopieren

Bei der Copy-Initialisierung wird aus einem vorhandenen Vektor ein neuer erstellt: std::vector<int> copy = source;. Die direkte Initialisierung erreicht dasselbe mit runden Klammern: std::vector<int> copy(source);. Wenn das Ziel bereits existiert, verwenden Sie eine Zuweisung: destination = source;. Dabei werden die Elemente des Ziels ersetzt. Binden Sie für diese Schreibweisen <vector> ein.

Führen Sie dieses Beispiel aus:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

#include <cstddef>
#include <iostream>
#include <vector>

int main() {
    const std::vector<int> source{2, 4, 6};
    std::vector<int> copy = source;
    std::vector<int> destination{9};
    destination = source;

    for (std::size_t i = 0; i < copy.size(); ++i) {
        if (i != 0) {
            std::cout << ' ';
        }
        std::cout << copy[i];
    }
    std::cout << '\n';
    for (std::size_t i = 0; i < destination.size(); ++i) {
        if (i != 0) {
            std::cout << ' ';
        }
        std::cout << destination[i];
    }
    std::cout << '\n';
}
2 4 6
2 4 6

Dieses Programm gibt jeden kopierten Vektor in einer eigenen Zeile aus. Die in std::vector<int> gespeicherten Integerwerte sind Werte. Wenn Sie also eine Ganzzahl in einem Vektor ändern, ändert sich die entsprechende Ganzzahl im anderen Vektor nicht.

Einen Bereich mit dem Bereichskonstruktor von vector kopieren

Der Bereichskonstruktor verwendet einen halboffenen Iteratorbereich: Der erste Iterator ist enthalten, der zweite nicht. Verwenden Sie runde Klammern, damit der Aufruf nicht mit der Initialisiererliste-Syntax verwechselt wird.

std::vector<int> copy(source.begin(), source.end()); erstellt eine Kopie des gesamten Bereichs. Für einen Teilbereich verwenden Sie std::vector<int> middle(source.begin() + 1, source.end() - 1);, sofern diese Iteratoren die gewünschten Elemente bezeichnen.

Die erste Deklaration kopiert alle Elemente; die zweite kopiert in diesem Beispiel den inneren Bereich. Beide Iteratoren müssen einen gültigen Bereich im selben Quellvektor bezeichnen. Das ist eine praktische Wahl, wenn ein neuer Zielvektor für eine vollständige Kopie oder einen Teilbereich benötigt wird.

Einen Bereich mit std::copy kopieren

std::copy schreibt in einen bereits vorhandenen Zielbereich. Binden Sie <algorithm> ein und stellen Sie vor dem Kopieren sicher, dass das Ziel mindestens so viele Elemente wie der Quellbereich enthält. Der Algorithmus vergrößert einen Vektor nicht selbst.

std::vector<int> destination(source.size()); gefolgt von std::copy(source.begin(), source.end(), destination.begin()); stellt einen ausreichend großen Zielbereich für die Quelle bereit.

Für einen Teilbereich übergeben Sie dessen Anfangs- und Enditeratoren und sorgen Sie dafür, dass genügend Zielelemente für diesen Bereich vorhanden sind. Quell- und Zielbereich dürfen sich nicht auf eine Weise überschneiden, die die Anforderungen des Algorithmus verletzt.

Kopierte Elemente mit std::back_inserter anhängen

Um Elemente anzuhängen und den Vektor bei Bedarf wachsen zu lassen, binden Sie <algorithm> und <iterator> ein und verwenden Sie std::back_inserter:

Zum Beispiel hängt std::vector<int> destination{10}; gefolgt von std::copy(source.begin(), source.end(), std::back_inserter(destination)); die Quellelemente an.

Die ursprüngliche 10 bleibt am Anfang stehen, gefolgt von den Werten aus der Quelle. Diese Form ist nützlich, wenn das Ziel bereits Elemente enthält oder seine endgültige Größe nicht im Voraus festgelegt wird.

Elemente mit einer Schleife und push_back kopieren

Eine Schleife macht die Operation für jedes einzelne Element sichtbar. push_back fügt jeden kopierten Wert am Ende hinzu und erweitert damit ein bereits vorhandenes Ziel.

Eine einfache Schleife lautet nach der Deklaration von std::vector<int> destination;: for (const int& value : source) { destination.push_back(value); }.

Für gewöhnliche Kopien sind der Copy-Konstruktor oder der Bereichskonstruktor des Vektors meist klarer. Eine Schleife eignet sich, wenn jedes Element beim Hinzufügen umgewandelt oder gefiltert werden muss. Wie bei den Standardoperationen des Vektors wird jedes Element entsprechend seinem Typ kopiert.

Zielelemente mit assign ersetzen oder mit insert einfügen

Verwenden Sie assign(first, last), wenn das Ziel durch einen Bereich ersetzt werden soll. Mit insert(position, first, last) fügen Sie den Quellbereich an einer bestimmten Position ein und erhalten dabei die übrigen Elemente des Ziels.

Mit destination.assign(source.begin(), source.end()); ersetzen Sie den Inhalt. Mit destination.insert(destination.begin(), source.begin(), source.end()); fügen Sie den Quellbereich am Anfang ein.

Die Einfügeposition muss ein gültiger Iterator in den Zielvektor sein. Wenn das Einfügen den Speicher des Vektors neu zuweist, werden alle Iteratoren, Zeiger und Referenzen auf seine Elemente ungültig. Findet keine Neuzuweisung statt, werden Iteratoren und Referenzen an oder hinter der Einfügeposition trotzdem ungültig; davor bleiben sie gültig. Holen Sie betroffene Iteratoren und Referenzen nach dem Einfügen erneut ein.

Verstehen, was beim Kopieren eines Vektors dupliziert wird

Ein std::vector speichert seine Elemente zusammenhängend und verwaltet diesen Elementspeicher selbst. Beim Kopieren entsteht ein separater Vektor mit Kopien der Elemente. Bei std::vector<int> werden die Integerwerte kopiert. Eine spätere Zuweisung an ein Element des einen Vektors ändert daher nicht den Wert im anderen.

Bei anderen Elementtypen richtet sich das Verhalten nach deren Kopieroperation. Beim Kopieren eines Vektors mit rohen Zeigern werden beispielsweise die Zeigerwerte kopiert; die referenzierten Objekte werden nicht neu erstellt. Bei Smart-Pointern richtet sich das Kopieren nach deren eigener Semantik, etwa der gemeinsamen Besitzverwaltung bei std::shared_ptr. Ein separater Vektor bedeutet daher nicht immer, dass die Objekte hinter seinen Elementen unabhängig sind.

Eine Methode zum Kopieren eines Vektors auswählen

Verwenden Sie den Copy-Konstruktor oder den Bereichskonstruktor, um einen neuen Vektor zu erstellen. Mit dem Copy-Zuweisungsoperator oder assign ersetzen Sie ein vorhandenes Ziel. insert fügt einen Bereich an einer bestimmten Position ein; mit std::copy und std::back_inserter können Sie Elemente anhängen und das Ziel dabei wachsen lassen. Verwenden Sie std::copy mit einem passend dimensionierten Ziel, wenn Sie in einen bereits vorhandenen Elementbereich schreiben möchten. Eine Schleife mit push_back ist nützlich, wenn beim Kopieren zusätzlich für jedes Element eine eigene Verarbeitung nötig ist.

Für eine vollständige Kopie in einen neuen Vektor ist der Copy-Konstruktor die naheliegende Wahl; für ausgewählte Elemente verwenden Sie den Bereichskonstruktor. Bei einem bestehenden Vektor wählen Sie eine Zuweisung oder assign, um den Inhalt zu ersetzen, insert, um Elemente an einer Position einzufügen, oder std::back_inserter, um sie anzuhängen.