¿Debo usar el rpp compartido o el rpp único? [duplicar]
Esta pregunta ya tiene una respuesta aquí:
- ¿Qué tipo de puntero utilizo cuando? 4 respuestas
Tengo una pregunta acerca de std::unique_ptr
y std::shared_ptr
. Sé que hay un montón de preguntas sobre cuándo usar cuál, pero todavía no estoy seguro de si lo entiendo correctamente. Leí en algún lugar que la opción predeterminada para smart pointer debería ser std::unique_ptr
, pero según lo entiendo, para mis necesidades debería usar std::shared_ptr
. Por ejemplo, tengo:
class B;
class A
{
private:
B* b;
public:
B* getB();
};
A::getB()
{
return b;
}
Así que básicamente la clase A
posee puntero al objeto de tipo B
y hay un método que devuelve este puntero. Si creo getter, asumo que alguna otra clase puede acceder a este puntero y por lo tanto debería ser shared_ptr
en lugar de unique_ptr
. ¿Tengo razón o aún no lo entiendo?
5 answers
Respuesta corta: depende.
Depende de si el puntero devuelto por getB
puede ser almacenado/utilizado en algún lugar mientras que el propietario A ha salido del ámbito. La diferencia es sobre propiedad no sobre cuántos punteros tienes.
- Si la A todavía existe cuando se utiliza el resultado de
getB
, se puede almacenar unaunique_ptr
y devolver un puntero plano (o una referencia sigetB
nunca puede devolvernullptr
). Eso expresa "A posee B, y nadie más lo hace". - Si la A puede salir del ámbito mientras está usando / sosteniendo el resultado de
getB
, pero la B debe salir del ámbito junto con (o poco después) la A, almacenar ashared_ptr
y devolver aweak_ptr
. - Si es posible que muchos objetos, incluidos los que llaman de
getB
, pueden aferrarse a la B y no hay un solo propietario claro, almacenar y devolvershared_ptr
s.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-07 04:47:27
Supongamos, por ejemplo, que un puntero es realmente necesario y simplemente B b;
no lo corta (tal vez B es polimórfico, por ejemplo).
Escenario alfa
Entonces, A es el propietario de a B.
private:
std::unique_ptr<B> b;
Y getB
proporciona una visión de ese B.
public:
B& getB();
B& A::getB()
{
return *b;
}
Escenario beta
A es uno de los propietarios de a B.
private:
std::shared_ptr<B> b;
Y A puede dar propiedad de esa B a otros.
public:
std::shared_ptr<B> getB();
std::shared_ptr<B> A::getB()
{
return b;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-14 09:38:13
Devuelve un puntero desnudo, no un shared_ptr
, por lo que hacer que el puntero sea compartido no resolverá nada. Devuelve un shared_ptr
, o usa un unique_ptr
. Trate de pensar en cómo se puede implementar lo posible shared_ptr
y creo que esto debería aclarar mi punto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-14 09:35:59
Creo que tienes razón.
Si solo contaras el puntero B
como miembro privado en A
, creo que usaría un std::unqiue_ptr
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-14 09:36:02
No hay suficiente información en la pregunta.
Los punteros inteligentes capturan e implementan semántica de propiedad. Si el objeto A
posee el objeto B
, por lo que destruir el A
debería destruir el B
, entonces use unique_ptr
. Pero unique_ptr
no hace un buen tipo de retorno aquí. Solo sería el miembro y aún así devolverías un puntero desnudo.
Si obtener el B
significa que el cliente puede continuar usando el B
indefinidamente, entonces use shared_ptr
, porque eso sería compartido propiedad.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-14 09:38:16