2013-04-11 30 views
9

Ich brauche Zeiger der Instanzen einer Klasse zu erstellen, und das Programm weiß nicht zur Kompilierzeit, wie viele Zeiger ich erstellen werde. Zum Löschen dachte ich darüber nach, die Zeiger in einem Vektor zu speichern und dann einzeln zu löschen. Würde die Verwendung von Smart Pointers einen saubereren Weg zu gehen? Und wenn man nicht intelligente Zeiger verwenden möchte, würde diese Verwendung von Vektor als sauber angesehen werden?Löschen von Vektor von Zeigern

Mindestcode:

#include <vector> 
using namespace std; 

class Foo { 
public: 
    Foo(); 
}; 
Foo::Foo(){} 
void createFooVector(int nb, std::vector<Foo*> &v){ 
    for(int i=0;i<nb;i++){ 
     Foo* f = new Foo(); 
     v.push_back(f); 
    } 
} 
int main(int argc, char *argv[]){ 
    std::vector<Foo*> v; 
    createFooVector(5,v); 
    while (!v.empty()){ 
     Foo* f = v.back(); 
     v.pop_back(); 
     delete f; 
    } 
} 
+2

Brauchen Sie wirklich einen Behälter mit Zeigern? Können Sie Ihre 'Foo' Objekte nicht als Werte speichern (' std :: vector ')? Wäre es nicht auch klarer, wenn 'createFooVector' einen neuen Vektor zurückgibt, anstatt den als Argument angegebenen zu modifizieren? –

+0

@LucTourail Ich benutze Zeiger aus diesem Grund: http://stackoverflow.com/questions/15471193/vector-of-virtual-class-are-pointers-the-clean-way-to-go ... dies konnte nicht in dem Code gesehen werden, den ich hier aber zeige, versucht, es minimal zu halten – Vince

Antwort

3

Ich würde vorschlagen, entweder eine boost::pointer_vector verwenden, eine std::vector<std::unique_ptr<Foo>>, oder rollen Sie Ihre eigenen Foo Manager-Klasse aus, die eine vector<Foo*> hält und kümmert sich um Löschungen in den Konstruktor (Sie sollten dies als „Experte“ Lösung sehen, und nur Versuch wenn Sie die Ausnahmesicherheit vollständig verstehen). Sie möchten die Löschung nicht manuell vornehmen, was leicht zu Fehlern führen kann.

+0

Ich würde die Manager-Lösung zwar nicht empfehlen; Chancen sind das OP wird es nicht sicher genug machen im Hinblick auf Ausnahmen ... –

+0

@MatthieuM. Sehr richtig. Ich habe dazu eine Warnung hinzugefügt. – juanchopanza

1

Der Code ist in Ordnung. Die Verwendung von Smartpointern sollte jedoch die bevorzugte Wahl sein (weniger Code zum Schreiben und viel weniger Möglichkeiten für Speicherfehler).

1

Wäre die Verwendung von Smart Pointers ein sauberer Weg zu gehen?

Ja.

Und wenn man nicht intelligente Zeiger verwenden möchte, würde diese Verwendung von Vektor als sauber angesehen werden?

Ich habe keine Ideen, warum jemand nicht verwenden intelligente Zeiger in C++ will, wenn es keine Hausaufgaben sind ... Aber ich denke, es ist besser, so etwas wie boost::pointer_containers in diesem Fall zu verwenden.

1

Wenn Sie keine Klassen verwenden, die von Foo abgeleitet sind, und Foo relativ kostengünstig zu kopieren ist, verwenden Sie einfach vector<Foo>.

Wenn Ihr Compiler die Bewegungssemantik unterstützt, sollte es kein Problem geben.

+1

Ob es teuer ist, die Dinge wenig zu konstruieren, ich denke, du hast gedacht, dass es teuer ist, * zu kopieren *. Mit der Umzugs-Semantik ist das allerdings kein großes Problem ... und im schlimmsten Fall kann man das neue 'emplace_back'-Mitglied verwenden. –

+0

@Matthieu Ja, bewegen Semantik alles ändern. Um zu verdeutlichen, was ich meinte, um einen Wert in einen Vektor zu schieben, musst du ihn konstruieren, dann konstruiert die Vektorkopie eine andere. Ich wollte auf die Notwendigkeit hinweisen, die Konstruktion von Werten im Allgemeinen zu berücksichtigen. Ich werde aktualisieren, um 'copy construct' zu sagen. –

Verwandte Themen