2017-06-12 2 views
0

Ich habe eine Klasse, die eine std::vector Zeiger auf eine Basisklasse, die verschiedene abgeleitete Klassen hat. Wie rufe ich ihre Destruktoren aus der Klasse vector?So rufen Sie den Destruktor einer abgeleiteten Klasse in einem Vektor in einer anderen Klasse

holder.h

class holder 
{ 
public: 
    void add_stuff(); 
    void do_stuff();   
private: 
    std::vector<base*> vect; 
}; 

holder.cpp

void holder::add_stuff(base* to_add) { 
    vect.push_back(to_add); 
} 

void holder::do_stuff() { 
    vect[0]->say_words(); 
    delete vect[0]; //<--<--<-- I want to delete the object now 
} 

jetzt aufhören Fühlen Sie sich frei, wenn Sie wissen, was ich falsch mache. Ich habe die Grundlagen für den Rest des Codes aufgenommen, für den Fall, dass ich gerade weit weg bin.

base.h

class base 
{ 
public: 
    base(); 
    virtual ~base(); 
    virtual void say_words() = 0; 
}; 

derived.h

class derived : public base 
{ 
public: 
    derived(); 
    ~derived(); 
    void say_words(); 
}; 

derived.cpp

derived::derived() {} 
derived::~derived() {} 

void derived::say_words() { 
    cout << "Words!" << endl; 
} 

main.cpp

holder hold; 
holder* H = &hold; 
int main(){ 
    base* d = new derived(); 
    H->add_stuff(d); 
    H->do_stuff(); 
} 
+13

Nicht. Verwenden Sie ein 'std :: unique_ptr' oder' std :: shard_ptr' anstelle eines rohen Zeigers und verwenden Sie 'erase' auf dem Vektor zum Entfernen. Das wird die Speicherverwaltung für Sie übernehmen (das ist eine gute Sache). – NathanOliver

+3

Pseudocode nicht posten. Posten [MCVE]. – Yakk

+0

Was ist die wirkliche Einschränkung für das Zerstören von Objekten an genau diesem Punkt im Code? – PerelMan

Antwort

0

Wie kann ich ihre Destruktoren aus der Klasse vector aufrufen?

Sie bereits sind, auf Grund der Tatsache, dass die ~base destructor als virtual markiert. Der Aufruf von delete für einen Zeiger auf die Basisklasse ruft automatisch alle abgeleiteten Destruktoren für Sie auf. Das ist WHY der Basisklasse-Destruktor muss in erster Linie als virtual deklariert werden.

Was Sie vermissen, obwohl, wird das Objekt Zeiger von Ihrem std::vector, nachdem Sie das Entfernen delete das Objekt, zum Beispiel:

void holder::do_stuff() { 
    vect[0]->say_words(); 
    delete vect[0]; // <-- calls all destructors of this object! 
    vect.erase(vect.begin()); // <-- add this line! 
} 

Sie wollen nicht ungültige Zeiger in Ihrem Container zu verlassen.

Verwandte Themen