Ich komme aus Java in C ++ und habe eine allgemeine Design-Situation, in der ich ein Element (ein nicht primitives Element) habe, das ich aus einem std :: vector entfernen möchte.
in Java würde ich etwas schreiben wie: arrayList.remove (arrayList.indexOf (myClassInstance));
in C ++, mit einem std :: vector, was ist der beste / performanteste / sauberste Weg, dies zu tun?
Das Beste, was ich mir vorstellen kann, ist, einen Verweis auf die Instanz zu erstellen, nach der ich suche, und dann durch den Vektor zu iterieren, bis ich diese Referenz finde. im Wesentlichen, um die Speicheradresse jedes Elements in dem Vektor mit der Referenz zu vergleichen, bis ich eine Übereinstimmung erhalte.
Bin ich auf dem richtigen Weg? oder gibt es einen besseren Weg? (Vielleicht verwende ich einen anderen Std-Container, ich habe bisher nur std :: vector verwendet.)
Verwenden Sie std::find
, um das Element zu finden, und vector::erase
, um es zu entfernen.
std::find
durchläuft im Wesentlichen den Vektor, um das Element zu finden, und Sie können mit einem einfachen Vektor nicht besser sein (das gleiche gilt für Java ArrayList
). Ob Sie einen anderen Container verwenden sollten, hängt von Ihren Anforderungen ab.
Wenn Sie linear durch den Vektor suchen möchten,
%Vor%Wenn Sie ein Prädikat haben und alle Objekte entfernen möchten, die mit dem Prädikat übereinstimmen, dann:
%Vor%Keine dieser Methoden ist die leistungsstärkste Methode, da sie eine lineare Suche erfordern. Selbst wenn Ihr Element zu einem frühen Zeitpunkt gefunden wird, ist das Löschen teuer, da alle anderen Elemente durch eine Position verschoben werden müssen. p>
Die Verwendung von std :: list würde die letzteren betreffen: Die Suche wäre linear, aber das Löschen wäre eine konstante Zeit.
Wenn es möglich ist, Ihre Elemente in einem assoziativen Container zu speichern, der eine Schlüsselsuche verwendet, wäre das effizienter: O (log N) Lookup und konstante Zeitentfernung.
Eine Hash-Map kann sogar besser sein, in der Nähe einer konstanten Zeitsuche und -entfernung.
Für was Sie vorschlagen, d. h. Löschen durch den Zeiger des Objekts, könnten Sie std :: set für Ihren Typ T verwenden. Verwenden Sie dann mySet.erase( pt );
, wobei pt Ihr Zeiger ist. Sie müssen natürlich die Lebensdauer Ihrer Zeiger verwalten, aber die Tatsache, dass Sie wissen, welche Sie aus Ihrer Sammlung löschen möchten, legt nahe, dass Sie eine Kopie davon an anderer Stelle haben.
Sie könnten std :: set, SharedPtrLess & gt;
verwendenwo Sie SharedPtrLess wie folgt definieren:
%Vor%