weak_ptr unique_ptr smart shared_ptr pointer example create c++ c++11 shared-ptr unique-ptr

smart - unique_ptr c++



Deleter escriba en unique_ptr vs. shared_ptr (1)

Esta pregunta ya tiene una respuesta aquí:

Pensé que es muy curioso cuando descubrí que el estándar define std::unique_ptr y std::shared_ptr de dos maneras totalmente diferentes con respecto a un Deleter que puede poseer el puntero. Aquí está la declaración de cppreference::unique_ptr y cppreference::shared_ptr :

template< class T, class Deleter = std::default_delete<T> > class unique_ptr; template< class T > class shared_ptr;

Como puede ver, unique_ptr "guarda" el tipo del objeto Deleter como un argumento de plantilla. Esto también se puede ver en la forma en que el Deleter se recupera del puntero más adelante:

// unique_ptr has a member function to retrieve the Deleter template< class T, class Deleter = std::default_delete<T> > Deleter& unique_ptr<T, Deleter>::get_deleter(); // For shared_ptr this is not a member function template<class Deleter, class T> Deleter* get_deleter(const std::shared_ptr<T>& p);

¿Puede alguien explicar lo racional detrás de esta diferencia? Claramente estoy a favor del concepto para unique_ptr ¿por qué esto no se aplica a shared_ptr también? Además, ¿por qué get_deleter sería una función no miembro en el último caso?


Aquí puede encontrar la propuesta original de punteros inteligentes: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html

Responde a su pregunta con bastante precisión:

Dado que el eliminador no es parte del tipo, cambiar la estrategia de asignación no rompe la compatibilidad de fuente o binaria, y no requiere una recompilación del cliente.

Esto también es útil porque brinda a los clientes de std::shared_ptr poco más de flexibilidad, por ejemplo, shared_ptr instancias shared_ptr con diferentes eliminadores se pueden almacenar en el mismo contenedor.

Además, debido a que las implementaciones shared_ptr necesitan un bloque de memoria compartida de todos modos (para almacenar el recuento de referencia) y porque ya debe haber una sobrecarga en comparación con los punteros sin procesar, agregar un borrado de tipo borrado no es un gran problema aquí.

unique_ptr otro lado, unique_ptr está diseñado para no tener gastos generales y cada instancia tiene que incrustar su eliminador, por lo que convertirlo en una parte del tipo es lo más natural.