2016-06-13 15 views
-1

Betrachten Sie das folgende erfundene Beispiel:Dynamisch zugeordnete Objekte in statischer Map. Löschen notwendig?

class AllocatedClass { 
public: 
    AllocatedClass() : dummy(0) {} 
private: 
    int dummy; 
}; 

class AllocatingClass { 
public: 
    AllocatingClass() : list() {} 
    ~AllocatingClass() { 
     // CANNOT delete the elements in list here because there may 
     // be more than on instance of AllocatingClass sharing the same 
     // static list 
    } 
    AddNewObject() { 
     list.push_back(new AllocatedClass()); 
    } 
private: 
    static std::vector<AllocatedClass*> list; 

}; 

In Implementierung Datei

std::vector<AllocatedClass*> AllocatingClass::list; 

Lässt man einmal beiseite, ob mehrere Instanzen einer Klasse eine gute Idee, eine Liste der dynamisch zugewiesenen Objekte teilen sollten, ist Gibt es eine Möglichkeit, diese neuen AllocatedClass-Objekte am Ende des Programms zu bereinigen? Ist es wichtig, dass diese nie gelöscht werden, wenn ich sie nicht bis zum Anwendungsende löschen möchte?

+4

Was ist mit der Verwendung von [std :: shared_ptr] (http://en.cppreference.com/w/cpp/memory/shared_ptr)? – WhiZTiM

+3

Jedes 'new()' muss sehen, dass es 'delete' entspricht. –

+0

Dieser Code ist einfach nicht kompilierbar. VTC. – SergeyA

Antwort

2

Wenn die Lebensdauer des Objekts die Lebensdauer der Ausführung des Programms ist, muss der Speicher nicht mit Code freigegeben werden. Der Speicher ist automatisch frei.

Viele Linux-Befehlszeilentools geben ihren Speicher im Code aus Leistungsgründen nicht frei. (Schneller zum automatischen Freigeben von Seiten des Speichers, als jedes Objekt einzeln freizugeben.)

Eine andere Strategie besteht darin, eine separate Liste eindeutiger AllocatedClass-Instanzen beizubehalten und sie später aus dieser Liste zu entfernen (Eigentümerwechsel der Objekte)). Wie std::list<AllocatedClass*> to_be_freed.

+9

Destruktoren können Nebenwirkungen haben, und beim Löschen geht es nicht immer nur darum, Speicher freizugeben. – GManNickG

+1

Nichtsdestotrotz sind Programme, die Zeit zum Abschalten brauchen, sehr nervig. Wenn Sie also am Ende Ihres Programms den Freigabeschritt sicher eliminieren können und die Ausführungsdauer Ihres Programms verkürzt wird, dann sollten Sie sich dafür entscheiden. Stell nur sicher, dass du weißt, was du tust. –

-1

Die meiste Zeit (sehr nahe an der Zeit) sollte ein Objekt, das dynamisch zugewiesene Objekte erstellt, einen vom Programmierer definierten Destruktor haben, um den Speicher freizugeben, wenn das Objekt das Ende seiner Lebensdauer erreicht. AllocatingClass sollte einen Destruktor haben, da Sie dynamischen Speicher mit new zuweisen.

Dies sollte sowohl eine Methode zum Aufheben der Zuordnung von Speicher und Sicherheit bieten, damit Sie einen bereits gelöschten Zeiger nicht löschen.

+0

Das willst du nicht; 'list' ist statisch und geteilt, aber Sie löschen es bei der ersten' ~ AllocatingClass'. Wenn AllocatingClass ein Singleton ist, sollte es eine Art von Standardimplementierung davon verwenden. –

+0

@AndrewLazarus in der Frage, es heißt, die Möglichkeit der Freigabe dynamisch zugewiesenen Listen zu ignorieren. – Stephen

+0

Bei meiner Lektüre heißt es, nicht in einen Code-Krieg zu geraten, ob es ein akzeptabler Stil ist, nicht OK, Code zu schreiben, der in diesem Setup nicht funktioniert. –

1

gibt es eine Möglichkeit, diese neu zugewiesenen AllocatedClass Objekte am Ende des Programms zu bereinigen?

Eine Lösung besteht darin, std::shared_ptr zu verwenden und die Freigabe automatisch vorzunehmen.

#include <memory> 
#include <vector> 
#include <iostream> 

class AllocatedClass 
{ 
    public: 
     AllocatedClass(int n = 0) : dummy(n) {} 
     ~AllocatedClass() { std::cout << "I am being destroyed" << '\n'; } 
    private: 
     int dummy; 
}; 

class AllocatingClass 
{ 
    public: 
     AllocatingClass() {} 
     void AddNewObject(int num = 0) 
     { shared_list.push_back(std::make_shared<AllocatedClass>(num)); } 
    private: 
     static std::vector<std::shared_ptr<AllocatedClass>> shared_list; 
}; 

std::vector<std::shared_ptr<AllocatedClass>> AllocatingClass::shared_list; 

AllocatingClass ac; 

int main() 
{ 
    ac.AddNewObject(); 
    ac.AddNewObject(1); 
} 

Live Example

Beachten Sie, dass die Destruktoren automatisch für die Objekte genannt werden, die in den Vektor gesetzt wurden.

(BTW, ist es keine gute Idee, Ihre Mitgliedsvariable list zu nennen).

+0

LOL bei "Ich werde zerstört". Ich kann mir den Kommentar des "Vektors" vorstellen: "Jetzt bin ich der Tod, der Zerstörer der Welten." Das oder wahnsinniges Lachen. – user4581301

+0

Wenn die Objekte nicht tatsächlich geteilt werden, befinden sie sich nur innerhalb des "Vektors", dann würde "std :: unique_ptr" mehr Sinn ergeben als "std :: shared_ptr". Natürlich wäre es noch sinnvoller, den "Vektor" von "vector " in "vector " zu ändern und dann 'shared_list.push_back (std :: make_shared (num)) zu ändern. ; 'to' shared_list.push_back (num); ', und lassen Sie die STL den Speicher für Sie behandeln. –

Verwandte Themen