2011-11-20 12 views
6

Tengo una clase resource_manager que mantiene un std::vector<boost::shared_ptr<resource> > internamente. resource_manager es una clase de amigo de resource. Quiero resource s solo para ser creado/eliminado por resource_manager, por lo que hice sus constructores privados (que funciona bien).¿Cómo puedo llamar a un destructor privado desde un shared_ptr?

Sin embargo, si hago el destructor privado, el código no se compila porque el destructor es llamado por boost::shared_ptr, que no es un amigo de resource. Estoy pensando en hacer cumplir la regla "no eliminar por clientes" devolviendo solo const resource* desde el resource_manager, pero de alguna manera no estoy satisfecho con la seguridad que proporciona este método (¿qué pasa si un cliente pasa de un puntero a no const?)

Además de la solución obvia de no usar shared_ptr, ¿tiene alguna solución alternativa/mejor a mi problema?

+0

"cliente pasa de alguna manera a través de un puntero a no constante" la única forma en que podría hacer es decir, si lanzan usando const_cast. Desde la perspectiva de la "seguridad" no hay diferencia entre los punteros sin formato y shared_ptr, la diferencia radica en la administración del tiempo de vida, de la cual no estoy seguro de cómo manejaría sin shared_ptr. – ronag

+4

Un 'const resource *' no significa que no pueda eliminarlo. – UncleBens

+0

@UncleBens: ¿No? ¡Pensé que el compilador no debería permitirte llamar a una función no const en un const! ¿Estoy equivocado? ¿O esta regla no se aplica al destructor? –

Respuesta

11

Puede pasar un eliminador personalizado al puntero compartido. Por lo que sólo crear un funtor Deleter o función (hasta que) que a su vez es un friend de su clase:

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

¿Por qué siempre eres más rápido que yo con la misma idea? ¡Para! :( – Xeo

+0

@Xeo: Mejor elegir una porción diferente de la torta - ¡Tengo mis ojos firmemente en 'shared_ptr'! ;-) –

+1

Por cierto, debe crear una instancia del' SecretDeleter'. – Xeo

1

¿Quizás declaró shared_ptr<resource> como un amigo? shared_ptr no llama al constructor, y solo debe destruir si el administrador de recursos libera el puntero antes de que todos los clientes hayan destruido sus shared_ptrs. Esto no permitirá que los clientes rompan la protección, pero permitirá que los clientes mantengan un recurso activo frente a la "voluntad" del resource_manager.

+0

Parece que no funciona cuando probé –

Cuestiones relacionadas