2010-05-26 9 views

risposta

21

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).

+0

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

+0

Sai se esiste un motivo tecnico per 'construct' che non accetta argomenti? – inf

+0

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

1

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

+0

Da quanto ho capito, shared_ptr può essere definito a prendere un allocatore personalizzato: 'template shared_ptr (Y * p, D d, A a);' La domanda è, cosa succede per D se dovessi usare il pool di Boost? – myahya

+0

L'allocatore è per l'oggetto contatore – philsquared

4

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.

+2

Non potresti usare 'boost :: allocate_shared' con' boost :: pool_alloc'? – dvide