J'aimerais que ma classe ait un pointeur statique sur une région mémoire allouée dynamiquement. Je comprends comment l’initialiser - dans mon cas, je l’initialisera lorsque le premier objet en aura besoin. Cependant, je ne sais pas quand/où dans le code pour le libérer. Je voudrais le libérer quand le programme se termine.
Je pourrais peut-être libérer le pointeur dans le destructeur de mes objets, mais je devrais alors conserver un compte d'objets pour voir s'il était libre de le libérer lorsque l'objet était le dernier objet utilisé.
Y a-t-il une manière plus élégante de faire ceci?
S'il vous plaît, faites-moi savoir.
Merci, Jbu
Vous avez deux solutions ici:
Je vous suggère de faire 2, c'est une façon très propre de le faire.
Voici un exemple simple. Au lieu de faire ça
static Thing* things = new Thing(); // or whatever way to initialize, here or in a specific function
Vous ferez ça:
class ThingManager // or whatever name you like
{
public:
ThingManager( Thing* thing ) : m_thing( thing ) { }//or create it here? whatever solution suits your way of creating the data
~ThingManager() { delete m_thing; } // THAT's the important part!
Thing* instance() const { return m_thing; } // or whatever accessor you need, if you need one
private:
Thing* m_thing;
};
et alors
static ManagedThing thing; // now i can access it via thing.instance()
Lorsque le programme se termine, la variable statique (qui n'est plus un pointeur) sera détruite et son destructeur sera appelé pour le faire.
C'est écrit juste pour vous donner une idée de comment vous pouvez faire ça.
Jetez-le dans un pointeur intelligent. Il aura une durée de vie statique et sera détruit après le retour de main
:
static std::auto_ptr<T> thePointer;
Une autre option consiste à enregistrer votre propre fonction atexit
:
// static
void YourClass::freePointer(void)
{
delete getPointer();
}
// static
T* YourClass::getPointer(void)
{
if (!thePointer)
{
thePointer = new T;
atexit(freePointer);
}
return thePointer;
}
Ce qui aura le même effet. Une autre option que vous avez déjà mentionnée est de garder un compteur statique. Notez que vous pouvez réellement envelopper assez efficacement.
Du point de vue du système d’exploitation, il n’ya aucun intérêt à libérer de la mémoire lorsque le programme se termine, il ne fait que ralentir la résiliation. La résiliation de votre application détruit tout votre espace d'adressage, elle libère tout vous allouez sur le tas en une seule fois. appeler explicitement free
à l’arrêt de l’application ne fait que brouiller les indicateurs dans le tas qui sera jeté de toute façon.
La principale raison pour laquelle nous nous efforçons de tout libérer de manière explicite est de nous assurer que nous ne perdons pas de mémoire et que notre empreinte mémoire ne croît pas éternellement.
Mais si vous pouvez être certain que cela est statique, qu'il n'y en aura qu'un, et que vous ne pourrez pas le libérer en toute sécurité tant que tous vos autres objets n'auront pas été libérés, c'est un cas où il vaudrait mieux laisser l'application. la résiliation en prend soin pour vous.
Vous pouvez vous déclarer variable statique en tant que pointeur intelligent, puis lorsque le programme terminé, le pointeur alloué sera libéré.
je définirais un compteur statique dans la classe pour suivre le nombre d'instances d'objet au fur et à mesure que le destructeur s'exécute l'exécute décrémente le compteur et si counter == 0 libère la mémoire aussi .. tout comme vous