Quiero pasar un puntero compartido a una función. ¿Me puede ayudar con eso?
Claro, puedo ayudarte con eso. Supongo que tiene cierta comprensión de la semántica de propiedad en C ++. ¿Es eso cierto?
Sí, me siento razonablemente cómodo con el tema.
Bueno.
Ok, solo puedo pensar en dos razones para shared_ptr
argumentar:
- La función quiere compartir la propiedad del objeto;
- La función realiza alguna operación que trabaja específicamente en
shared_ptr
s.
Cual te interesa?
Estoy buscando una respuesta general, así que estoy interesado en ambos. Sin embargo, tengo curiosidad por saber a qué te refieres con el caso n. ° 2.
Ejemplos de tales funciones incluyen std::static_pointer_cast
comparadores personalizados o predicados. Por ejemplo, si necesita encontrar todos los shared_ptr únicos de un vector, necesita dicho predicado.
Ah, cuando la función realmente necesita manipular el puntero inteligente.
Exactamente.
En ese caso, creo que deberíamos pasar por referencia.
Si. Y si no cambia el puntero, desea pasar por referencia constante. No es necesario copiar, ya que no es necesario compartir la propiedad. Ese es el otro escenario.
Ok lo tengo. Hablemos del otro escenario.
¿En el que compartes la propiedad? Okay. ¿Cómo se comparte la propiedad conshared_ptr
?
Copiándolo.
Entonces la función necesitará hacer una copia de a shared_ptr
, ¿correcto?
Obviamente. Entonces, ¿lo paso por una referencia a const y lo copio en una variable local?
No, eso es una pesimización. Si se pasa por referencia, la función no tendrá más remedio que realizar la copia manualmente. Si se pasa por valor, el compilador elegirá la mejor opción entre una copia y un movimiento y la realizará automáticamente. Entonces, pase por valor.
Buen punto. Debo recordar eso " ¿Quieres velocidad? Pasar por valor " con más frecuencia.
Espere, ¿y si la función almacena el shared_ptr
en una variable miembro, por ejemplo? ¿No será una copia redundante?
La función puede simplemente mover el shared_ptr
argumento a su almacenamiento. Mover unshared_ptr
es barato porque no cambia ningún recuento de referencias.
Ah, buena idea.
Pero estoy pensando en un tercer escenario: ¿qué pasa si no quieres manipular shared_ptr
ni compartir la propiedad?
En ese caso, shared_ptr
es completamente irrelevante para la función. Si desea manipular el pointee, tome un pointee y deje que las personas que llaman elijan qué semántica de propiedad quieren.
¿Y debería tomar el pointee por referencia o por valor?
Se aplican las reglas habituales. Los punteros inteligentes no cambian nada.
Pasar por valor si voy a copiar, pasar por referencia si quiero evitar una copia.
Derecha.
Hmm. Creo que olvidaste otro escenario. ¿Qué sucede si quiero compartir la propiedad, pero solo dependiendo de una determinada condición?
Ah, un caso extremo interesante. No espero que eso suceda a menudo. Pero cuando suceda, puede pasar por valor e ignorar la copia si no la necesita, o pasar por referencia y hacer la copia si la necesita.
Me arriesgo a una copia redundante en la primera opción y pierdo un movimiento potencial en la segunda. ¿No puedo comerme el pastel y tenerlo también?
Si se encuentra en una situación en la que eso realmente importa, puede proporcionar dos sobrecargas, una tomando una referencia de valor constante y otra tomando una referencia de valor r. Uno copia, el otro se mueve. Una plantilla de función de reenvío perfecto es otra opción.
Creo que cubre todos los escenarios posibles. Muchas gracias.
const std::shared_ptr<myClass>& arg1