¿Debo usar el rpp compartido o el rpp único? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

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?

Author: kay, 2013-02-14

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 una unique_ptr y devolver un puntero plano (o una referencia si getB nunca puede devolver nullptr). 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 a shared_ptr y devolver a weak_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 devolver shared_ptrs.
 22
Author: Arne Mertz,
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;
}
 7
Author: R. Martinho Fernandes,
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.

 2
Author: Ivaylo Strandjev,
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.

 2
Author: tehlexx,
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.

 2
Author: Potatoswatter,
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