Kann ich std :: vectorAnimal * nach std :: vectorDog * umwandeln, ohne jedes Element zu betrachten?

8

Ich habe eine Basisklasse mit mehreren Klassen, die sie erweitern. Ich habe einige generische Bibliotheksprogramme, die einen Vektor erstellen, der Zeiger auf die Basisklasse enthält, so dass jede der Unterklassen funktioniert. Wie kann ich alle Elemente des Vektors in eine bestimmte Kindklasse umwandeln?

%Vor%

Meine naive Lösung würde etwa so aussehen:

%Vor%     
Beau Simensen 24.07.2009, 03:36
quelle

7 Antworten

10

Sie könnten std::transform verwenden. Es verwendet intern for() , aber Sie erhalten eine Implementierung mit zwei Zeichenfolgen:

%Vor%     
Kirill V. Lyadvinsky 24.07.2009 04:45
quelle
0

Ihr Code schreibt, wie geschrieben, eine Menge Nullzeiger in Ihren Hundevektor, wenn der Tiervektor andere Tierspezialisierungen enthält.

%Vor%     
paxos1977 24.07.2009 03:46
quelle
0

Es gibt zwei Möglichkeiten. Am einfachsten ist es, etwas wie remove_copy_if zu verwenden. Ich kann nicht erklären, warum sie es so nennen, aber es kopiert die Elemente von einem Container in einen anderen, die das Prädikat nicht erfüllen. Hier ist die Grundidee (ungetestet):

%Vor%

}

Ich denke, eine Möglichkeit, remove_copy_if zu betrachten, ist, sie als copy_unless zu betrachten.

Ein alternativer Ansatz besteht darin, den Iterator für den Vektor & lt; zu umbrechen, wenn Sie Ihren Code nur auf Iteratoren aufbauen. Tier * & gt; mit einem, der nur die Hunde aus der Sammlung zurückgibt. Der Hauptvorteil hier ist, dass Sie immer noch nur einen Container haben, aber natürlich zahlen Sie ein bisschen mehr, da Ihr Algorithmus über die gesamte Sammlung von Tieren navigieren wird.

%Vor%

Das ist sehr grob, aber ich hoffe, es zeigt Ihnen das Grundprinzip.

    
Richard Corden 24.07.2009 12:50
quelle
0

Normalerweise ist es nicht gut, dynamic_cast für Downcasting zu verwenden. Sie sollten Ihren Code wahrscheinlich umgestalten, damit Sie keine expliziten Downcasts verwenden müssen.

Weitere Informationen finden Sie CPP FAQ lite .

UPD Siehe auch Stroustrup-Seite (suchen Sie nach "Warum? kann ich einem Vektor keinen Vektor zuordnen? ")

    
Sad Developer 24.07.2009 04:09
quelle
0

Wenn Sie sagen, dass Sie garantieren können, dass jedes Element wirklich ein Hund ist, dann geben Sie einfach static_cast i.d.

ein %Vor%

Ich bekomme normalerweise immer eine reflexartige Reaktion von Leuten, dass das schlecht ist und du solltest immer dynamic_cast verwenden, aber in der Realität, wenn du Garantien über den Typ machen kannst, ist es vollkommen sicher und IMO eine vernünftige Sache .

Außerdem würde Ihre Garantie bedeuten, dass der neue Vektor die gleiche Größe hat, also reservieren Sie den gleichen Platz, um Zuweisungen in jedem push_back zu vermeiden. Als eine alternative Schleife habe ich einen Index verwendet, nur weil ich immer daran denke, dass das Iterieren mit einem Index schneller sein muss als ein Iterator, aber das ist wahrscheinlich Unsinn:)

    
Troubadour 04.08.2009 21:45
quelle
0

Wenn Sie sicherstellen können, dass Ihr std::vector<Animal*> nur Dog* enthält, können Sie reinterpret_cast verwenden.

    
PaulProgrammerNoob 29.11.2017 21:44
quelle
0

Das Kombinieren der std::transform -Methode mit einem static_cast (weil Sie sich seiner Sicherheit sicher sind) könnte folgendermaßen aussehen:

%Vor%     
Escualo 29.11.2017 22:09
quelle

Tags und Links