referencias referencia punteros por paso parametros llamadas ejemplos c++ visual-studio-2005

c++ - referencia - punteros en c ejemplos



Pasando punteros inteligentes por referencia (2)

Los punteros inteligentes son generalmente pequeños, por lo que pasar por valor no es un problema, pero hay algún problema al pasarles referencias; o más bien, ¿hay casos específicos donde esto no se debe hacer?

Estoy escribiendo una biblioteca de envoltorio y varias de mis clases envuelven objetos de puntero inteligente en la biblioteca subyacente ... mis clases no son punteros inteligentes, pero las API actualmente pasan objetos de puntero inteligente por valor.

ej. código actual:

void class::method(const AnimalPtr pAnimal) { ... }

se convierte en

void class::method(const MyAnimal &animal){...}

donde MyAnimal es mi nueva clase de envoltorio que encapsula AnimalPtr .

No hay garantía de que las clases de Wrapper no crezcan un día más que envolver un puntero inteligente, por lo que pasar por valor me pone nervioso.


Está bien pasar un puntero inteligente por referencia, excepto si se trata de un constructor. En un constructor, es posible almacenar una referencia al objeto original, que viola el contrato de los punteros inteligentes. Probablemente obtendrías corrupción de memoria si hicieras eso. Incluso si su constructor no almacena hoy la referencia, todavía desconfiaría porque el código cambia y es una cosa fácil de perder si decide más tarde que necesita mantener la variable por más tiempo.

En una función normal, no puede almacenar un parámetro de función como una referencia en ninguna parte porque las referencias deben establecerse durante su inicialización. Podría asignar la referencia a alguna variable sin referencia de vida más larga, pero eso sería una copia y, por lo tanto, aumentaría su vida útil de manera apropiada. Por lo tanto, en cualquier caso, no podría mantenerlo pasado cuando la función de llamada podría haberlo liberado. En este caso, es posible que obtenga una pequeña mejora en el rendimiento con una referencia, pero no planeo notarlo en la mayoría de los casos.

Así que yo diría - constructor, siempre pasa por valor; Otras funciones, pase por referencia si lo desea.


Debe pasar los punteros compartidos por referencia, no por valor, en la mayoría de los casos. Si bien el tamaño de un std::shared_ptr es pequeño, el costo de la copia implica una operación atómica (conceptualmente, un incremento atómico y una disminución atómica en la destrucción de la copia, aunque creo que algunas implementaciones logran hacer un incremento no atómico) .

En otros casos, por ejemplo std::unique_ptr es posible que prefiera pasar por valor, ya que la copia tendrá que ser un movimiento y documenta claramente que la propiedad del objeto se transfiere a la función (si no desea transferir propiedad, luego pase una referencia al objeto real, no a std::unique_ptr ).

En otros casos su kilometraje puede variar. Debe conocer qué es la semántica de la copia para su puntero inteligente y si debe pagar el costo o no.