Desidero che gli oggetti gestiti da un shared_ptr siano allocati da un pool, ad esempio l'interfaccia Pool di Boost, come può essere ottenuto?Allocatore personalizzato (pool) con boost shared_ptr
risposta
Ecco il codice per fare ciò che si vuole (probabilmente non verrà compilato come non ho spinta a portata di mano e sto scrivendo a memoria):
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();
ho implementato due volte, in due diversi progetti. In entrambi, le funzioni di creazione e distruzione sono state sincronizzate (è possibile aggiungere un blocco boost::mutex
all'utilizzo di allocator) ed erano membri di una classe factory (e la firma dello destroy
è stata modificata in void (YourClass*)
tramite l'utilizzo di boost::bind
).
È inoltre possibile evitare di scrivere due funzioni aggiuntive (destroy
e create
) vincolando direttamente object_pool<YourClass>::destroy
nel costruttore boost :: shared_ptr.
Sono troppo pigro per scrivere tutto questo ora :).
Modifica (spostato la mia risposta commento in qui per il codice di formattazione):
di impegnare la funzione di distruggere:
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
dovrebbe avere una durata più lunga della shared_ptr
(se il ClassFactory
l'istanza è stata cancellata, il puntatore passato all'istanza shared_ptr
non sarà più valido e si bloccherà l'app quando lo shared_ptr
elimina l'istanza YourClass
).
Queste sono preoccupazioni quasi ortogonali. shared_ptr
non ha alcun ruolo nell'assegnazione di oggetti.
Dove si è in questione si trova nella eliminazione della memoria non è più fatto riferimento. Se avete assegnato da qualcosa di diverso dal mucchio di default è necessario provide a custom deleter
Da quanto ho capito, shared_ptr può essere definito a prendere un allocatore personalizzato: 'template
L'allocatore è per l'oggetto contatore – philsquared
soluzione evidente:
creare la propria funzione make_shared
e applicare l'uso di questo metodo per shared_ptr
creato. Coloro che derivano dalla Regola saranno puniti.
Nota:
Sembra che ci sia una confusione con il ruolo del shared_ptr
. Il suo ruolo è di gestire la memoria di quanto tu abbia assegnato, tuttavia per farlo richiede una sua allocazione (contatore e deleter), quindi puoi passargli un allocatore per quelli.
Non potresti usare 'boost :: allocate_shared' con' boost :: pool_alloc'? – dvide
Grazie, questo è quello che stavo cercando. Sarei interessato a vedere come è fatto usando una classe factory, sto avendo problemi nel legare la funzione destroy. – myahya
Sai se esiste un motivo tecnico per 'construct' che non accetta argomenti? – inf
Recentemente ho fatto qualcosa di molto simile con una classe di pool basata su modelli e ne ho scritto qui: https://www.burgundywall.com/post/shared_pool – Kurt