Espacios de nombres
Variantes
Acciones

std::allocate_shared, std::allocate_shared_for_overwrite

De cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
Biblioteca de servicios
 
Gestión de memoria dinámica
Punteros inteligentes
(C++11)
(C++11)
(C++11)
(hasta C++17)
(C++11)
(C++23)
Asignadores de memoria
Recursos de memoria
Almacenamiento no inicializado
Algoritmos de memoria no inicializada
Algoritmos restringidos de memoria no inicializada
Apoyo para recolección de basura
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
Misceláneos
(C++20)
(C++11)
(C++11)
 
 
Definido en el archivo de encabezado <memory>
template< class T, class Alloc, class... Args >
shared_ptr<T> allocate_shared( const Alloc& alloc, Args&&... args );
(1) (desde C++11)
(T es no array)
template< class T, class Alloc >
shared_ptr<T> allocate_shared( const Alloc& alloc, std::size_t N );
(2) (desde C++20)
(T es U[])
template< class T, class Alloc >
shared_ptr<T> allocate_shared( const Alloc& alloc );
(3) (desde C++20)
(T es U[N])
template< class T, class Alloc >

shared_ptr<T> allocate_shared( const Alloc& alloc, std::size_t N,

                               const std::remove_extent_t<T>& u );
(4) (desde C++20)
(T es U[])
template< class T, class Alloc >

shared_ptr<T> allocate_shared( const Alloc& alloc,

                               const std::remove_extent_t<T>& u );
(5) (desde C++20)
(T es U[N])
template< class T, class Alloc >
shared_ptr<T> allocate_shared_for_overwrite( const Alloc& alloc );
(6) (desde C++20)
(T es not U[])
template< class T, class Alloc >
shared_ptr<T> allocate_shared_for_overwrite( const Alloc& alloc, std::size_t N );
(7) (desde C++20)
(T es U[])
1) Construye un objeto de tipo T y lo envuelve en un std::shared_ptr usando args como la lista de parámetros para el constructor de T. El objeto se construye como si fuera por la expresión ::new (pv) T(v) (hasta C++20)std::allocator_traits<A2>::construct(a, pv, v) (desde C++20), donde pv es un puntero interno void* al almacenamiento adecuado para contener un objeto de tipo T y a es una copia del asignador de memoria revinculado a std::remove_cv_t<T>. El almacenamiento suele ser más grande que sizeof(T) para usar una asignación tanto para el bloque de control del puntero compartido como para el objeto T. El constructor std::shared_ptr llamado por esta función habilita shared_from_this con un puntero al objeto recién construido de tipo T. Toda la asignación de memoria se realiza mediante una copia de alloc, que debe cumplir los requisitos de Allocator. Esta sobrecarga solo participa en la resolución de sobrecargas si T no es un tipo array.
2,3) Igual que (1), pero el objeto construido es un array posiblemente multidimensional cuyos elementos que no son de tipo array se inicializan como si fuera por la expresión std::allocator_traits<A2>::construct(a2, pv) donde a2 de tipo A2 es la copia del asignador de memoria revinculado para gestionar objetos de tipo std::remove_cv_t<std::remove_all_extents_t<T>>. La sobrecarga (2) crea un array de tamaño N a lo largo de su primera dimensión. Los elementos del array se inicializan en orden ascendente de sus direcciones y, cuando finaliza su tiempo de vida, se destruyen en el orden inverso al de su construcción original.
4,5) Igual que (2,3), pero los elementos del array se inicializan a partir del valor por defecto u. Si std::remove_extent_t<T> no es en sí mismo un tipo array, esto se realiza como si fuera la misma expresión de asignador que en (1), excepto que el asignador se reenvía a std::remove_cv_t<std::remove_all_extents_t<T>>. De lo contrario, esto se realiza como si se inicializaran todos los elementos que no son de tipo array del array (posiblemente multidimensional) con el elemento correspondiente de u usando la misma expresión de asignador que en (1), excepto que el asignador se vuelve a vincular al tipo std::remove_cv_t<std::remove_all_extents_t<T>>. La sobrecarga (4) crea un array de tamaño N a lo largo de la primera dimensión. Los elementos del array se inicializan en orden ascendente de sus direcciones y, cuando finaliza su tiempo de vida, se destruyen en el orden inverso al de su construcción original.
6) Igual que (1) si T no es un tipo array y (3) si T es U[N], excepto que el objeto creado es inicializado por defecto.
7) Igual que (2), excepto que los elementos individuales del array son inicializados por defecto.

Para allocate_shared, el objeto (o los elementos de tipo array individuales para (2-5)) (desde C++20) se destruyen a través de la expresión std::allocator_traits<A2>::destroy(a, p), donde p es un puntero al objeto y a es una copia del asignador de memoria pasado a allocate_shared, revinculado al tipo de objeto que se destruye.

Para allocate_shared_for_overwrite, el objeto (o elementos individuales si T es un tipo array) será destruido por p->~X(), donde p es un puntero al objeto y X es su tipo.

(desde C++20)

Contenido

[editar] Parámetros

alloc - El Allocator a usar.
args... - Lista de argumentos con los que se construirá una instancia de T.
N - Tamaño de array a usar.
u - El valor inicial con el que inicializar cada elemento del array.

[editar] Valor de retorno

std::shared_ptr de una instancia de tipo T.

[editar] Excepciones

Puede lanzar las excepciones lanzadas desde Alloc::allocate() o desde el constructor de T. Si se lanza una excepción, (1) no tiene efecto. Si se lanza una excepción durante la construcción de del array, los elementos ya inicializados se destruyen en orden inverso. (desde C++20)

[editar] Notas

Al igual que std::make_shared, esta función generalmente realiza solo una asignación y coloca tanto el objeto T como el bloque de control en el bloque de memoria asignado (el estándar recomienda pero no requiere esto, aunque todas las implementaciones conocidas hacen esto). Se almacena una copia de alloc como parte del bloque de control para que pueda usarse para desasignarlo una vez que los recuentos de referencias compartidas y débiles lleguen a cero.

A diferencia de los constructores de std::shared_ptr, std::allocate_shared no acepta un eliminador personalizado separado: el asignador de memoria proporcionado se usa para la destrucción del bloque de control y el objeto T, y para la desasignación de su bloque de memoria compartida.

std::shared_ptr admite tipos array (a partir de C++17), pero std::allocate_shared no. Esta funcionalidad se admite por boost::allocate_shared.

(hasta C++20)

Cuando se dice que un constructor habilita shared_from_this con un puntero ptr de tipo U*, significa que determina si U tiene una clase base no ambigua y accesible (desde C++17) que es una especialización de std::enable_shared_from_this, y si es así, el constructor evalúa la declaración:

if (ptr != nullptr && ptr->weak_this.expired())
  ptr->weak_this = std::shared_ptr<std::remove_cv_t<U>>(*this,
                                  const_cast<std::remove_cv_t<U>*>(ptr));

Donde weak_this es el miembro std::weak_ptr mutable oculto de std::enable_shared_from_this. La asignación al miembro weak_this no es atómica y entra en conflicto con cualquier acceso potencialmente concurrente al mismo objeto. Esto garantiza que las llamadas futuras a shared_from_this() compartirán la posesión con el std::shared_ptr creado por este constructor de puntero sin formato.

La prueba ptr->weak_this.expired() en el código de exposición anterior asegura que weak_this no se reasigna si ya indica un propietario. Esta prueba es necesaria a partir de C++17.


Macro de Prueba de característica
__cpp_lib_smart_ptr_for_overwrite
(para las sobrecargas (6,7))

[editar] Véase también

Construye un nuevo shared_ptr.
(función miembro pública) [editar]
Crea un puntero compartido que gestiona un nuevo objeto.
(plantilla de función) [editar]