2011-11-20 13 views
6

Ho una classe resource_manager che gestisce internamente uno std::vector<boost::shared_ptr<resource> >. resource_manager è una classe di amici di resource. Voglio che gli resource s vengano creati/eliminati solo da resource_manager, quindi ho reso privati ​​i suoi costruttori (che funziona bene).Come posso chiamare un distruttore privato da un shared_ptr?

Tuttavia, se si rende privato il distruttore, il codice non viene compilato perché il distruttore è chiamato da boost::shared_ptr, che non è un amico di resource. Sto pensando di far rispettare la regola "non cancellare dai clienti" restituendo solodal resource_manager, ma in qualche modo non sono soddisfatto della sicurezza offerta da questo metodo (e se un client si verifica in qualche modo attraverso un puntatore a non-const?)

Oltre all'ovvia soluzione di non utilizzare shared_ptr, avete qualche soluzione alternativa/migliore al mio problema?

+0

"client avviene in qualche modo attraverso un puntatore non-const" l'unico modo in cui potrebbe fare cioè se trasmettono usando const_cast. Dal punto di vista della "sicurezza" non vi è alcuna differenza tra i puntatori raw e shared_ptr, la differenza sta nella gestione del tempo di vita, di cui non sono sicuro come gestirmi senza shared_ptr. – ronag

+4

Una 'const resource *' non significa che non è possibile eliminarlo. – UncleBens

+0

@UncleBens: no? Pensavo che il compilatore non avrebbe permesso di chiamare una funzione non const su un const! Mi sbaglio? O questa regola non si applica al distruttore? –

risposta

11

È possibile passare un deleter personalizzato al puntatore condiviso. Quindi, basta creare un funtore di delezione o una funzione (fino a voi) che a sua volta è un friend della classe:

class Secret 
{ 
    ~Secret() { } 
    friend class SecretDeleter; 
    friend void SecretDelFunc(Secret *); 
}; 

class SecretDeleter 
{ 
public: 
    void operator()(Secret * p) { delete p; } 
}; 

void SecretDelFunc(Secret * p) { delete p; } 

std::shared_ptr<Secret> sp1(new Secret, SecretDeleter()); 
std::shared_ptr<Secret> sp2(new Secret, SecretDelFunc); 
+0

Perché sei sempre più veloce di me con la stessa idea? Smettila! :( – Xeo

+0

@Xeo: Meglio scegliere una fetta diversa della torta - Ho gli occhi ben fissi su 'shared_ptr'! ;-) –

+1

Btw, dovresti istanziare il' SecretDeleter'. – Xeo

1

Forse dichiarare shared_ptr<resource> come amico? shared_ptr non chiama il costruttore e dovrebbe solo distruggere se il gestore delle risorse rilascia il puntatore prima che tutti i client abbiano distrutto le loro shared_ptrs. Ciò non consentirà ai client di rompere la protezione, ma permetterà ai clienti di mantenere una risorsa in vita contro il "testamento" del resource_manager.

+0

Non sembra funzionare quando ho provato –

Problemi correlati