Usando std:: mover con std:: rpp compartido


Tengo una función definida de la siguiente manera:

void foo(std::shared_ptr<X> x) { ... };

Si declaro un rpp compartido a X:

std::shared_ptr<X> sourcePtr(new X(...));

Entonces puedo llamar a foo de la siguiente manera:

foo(std::move(sourcePtr));

O

foo(sourcePtr);

Entiendo que si utilizo la primera opción entonces sourcePtr se convierte en null. ¿También evita que el recuento de referencia se incremente?

Si eso no importa, ¿qué opción debería preferir? ¿Debería estar considerando algo más al tomar tal decisión?

Author: ksl, 2015-04-15

1 answers

Sí, si mueve el puntero compartido a la función, entonces:

  1. El original sourcePtr se convertirá en nulo, y

  2. El recuento de referencia no se modifica.

Si sabe que ya no necesitará el valor de sourcePtr después de la llamada a la función, moverlo a la función es una ligera optimización, ya que guarda un incremento atómico (y luego decremento, cuando sourcePtr sale del alcance).

Sin embargo, tenga cuidado de que el identificador sourcePtr sigue siendo válido para el resto del ámbito, solo que contiene un puntero nulo. Lo que significa que el compilador no se quejará si lo usa después del movimiento, pero si olvida que se movió desde, con toda probabilidad desreferenciará el null. Tiendo a usar mucho esta" optimización " move, y también me ha mordido un par de veces: se agrega más funcionalidad a la función, y si se olvida de deshacer el move, se obtiene un buen bloqueo.

Tan conmovedor cuando ya no lo necesitas es una ligera optimización junto con una ligera carga de mantenimiento. Depende de usted sopesar lo que es más importante en su caso.

Lo anterior asume que hay código que realmente usa sourcePtr entre su declaración y la llamada final a foo (gracias a @WhozCraig por señalarlo). Si no lo hay, sería mucho mejor crear el puntero justo en el sitio de la llamada:

foo(std::make_shared<X>(...));

De esta manera, usted ahorra la misma cantidad de operaciones atómicas, y usted no tenga un puntero compartido vacío potencialmente peligroso por ahí.

 34
Author: Angew,
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-04-15 08:02:21