Je veux que les objets gérés par un shared_ptr soient alloués à partir d'un pool, disons l'interface Pool de Boost, comment cela peut-il être réalisé?Attribution personnalisée (pool) avec boost shared_ptr
Répondre
Voici le code pour faire ce que vous voulez (probablement ne compilera pas que je n'ai pas coup de pouce à la main et je l'écris de la mémoire):
class YourClass; // your data type, defined somewhere else
boost::object_pool<YourClass> allocator;
void destroy(YourClass* pointer)
{
allocator.destroy(pointer);
}
boost::shared_ptr<YourClass> create()
{
// usage of object_pool<??>::construct requires that you have a
// YourClass::YourClass(void) defined. If you need to pass arguments
// to the new instance, you need to do that separately.
//
// for example using a YourClass::Initialize(your,parameters,here) method
// before returning from this function
return boost::shared_ptr<YourClass>(allocator.construct(), &destroy);
}
// usage:
boost::shared_ptr<YourClass> newObject = create();
Je mis en œuvre cette fois, en deux projets différents. Dans les deux, les fonctions créer et détruire ont été synchronisées (vous pouvez ajouter un verrou boost::mutex
autour de l'utilisation de l'allocateur) et ils étaient membres d'une classe d'usine (et la signature destroy
a été modifiée à void (YourClass*)
en utilisant boost::bind
).
Vous pouvez également éviter d'écrire deux fonctions supplémentaires (destroy
et create
) en liant object_pool<YourClass>::destroy
directement dans le constructeur boost :: shared_ptr. Je suis trop paresseux pour écrire tout ça maintenant :).
Modifier (déplacé mon commentaire de réponse ici pour la mise en forme de code):
Pour lier la détruire fonction:
class ClassFactory
{
boost::object_pool<YourClass> allocator;
public:
boost::shared_ptr<YourClass> create()
{
return boost::shared_ptr<YourClass>(
allocator.construct(),
boost::bind(&ClassFactory::destroy, this, _1));
}
void destroy(YourClass* pointer)
{
allocator.destroy(pointer);
}
};
ClassFactory
devrait avoir une durée de vie plus longue que la shared_ptr
(si le ClassFactory
instance est supprimée, le pointeur this transmis à l'instance shared_ptr
sera invalide - et écrase votre application lorsque le shared_ptr
supprime l'instance YourClass
).
Ce sont des préoccupations presque orthogonales. shared_ptr
ne joue aucun rôle dans allocation d'objets.
Où est concerné est dans la suppression de la mémoire n'est plus référencée. Si vous avez alloué d'autre chose que le tas par défaut, vous devrez provide a custom deleter
Si je comprends bien, shared_ptr peut être défini pour prendre un allocateur personnalisé: template '
L'allocateur est pour l'objet compteur – philsquared
solution Evident:
Créer votre propre fonction make_shared
et d'appliquer l'utilisation de cette méthode pour créer shared_ptr
. Ceux qui dérivent de la Règle seront punis.
Note:
Il semble y avoir une confusion avec le rôle du shared_ptr
. Son rôle est de gérer la mémoire que vous avez allouée, mais pour ce faire, il nécessite une certaine allocation de son propre (compteur et deleter), ainsi vous pouvez lui passer un allocateur pour ceux-ci.
Vous ne pourriez pas utiliser 'boost :: allocate_shared' avec' boost :: pool_alloc'? – dvide
Merci, c'est ce que je cherchais. Je serais intéressé de voir comment cela se fait en utilisant une classe d'usine, j'ai des problèmes dans la liaison de la fonction de destruction. – myahya
Savez-vous s'il existe une raison technique pour que 'construct' ne prenne aucun argument? – inf
J'ai récemment fait quelque chose de très similaire avec une classe de pool de templates et j'ai écrit à ce sujet ici: https://www.burgundywall.com/post/shared_pool – Kurt