std:: allocate_shared, std:: allocate_shared_for_overwrite
|
Definido en el encabezado
<memory>
|
||
|
template
<
class
T,
class
Alloc,
class
...
Args
>
shared_ptr < T > allocate_shared ( const Alloc & alloc, Args && ... args ) ; |
(1) | (desde C++11) |
|
template
<
class
T,
class
Alloc
>
shared_ptr < T > allocate_shared ( const Alloc & alloc, std:: size_t N ) ; |
(2) | (desde C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr < T > allocate_shared ( const Alloc & alloc ) ; |
(3) | (desde C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr
<
T
>
allocate_shared
(
const
Alloc
&
alloc,
std::
size_t
N,
|
(4) | (desde C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr
<
T
>
allocate_shared
(
const
Alloc
&
alloc,
|
(5) | (desde C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr < T > allocate_shared_for_overwrite ( const Alloc & alloc ) ; |
(6) | (desde C++20) |
|
template
<
class
T,
class
Alloc
>
shared_ptr
<
T
>
allocate_shared_for_overwrite
(
const
Alloc
&
alloc,
|
(7) | (desde C++20) |
Asigna memoria para un objeto utilizando una copia de
alloc
(reconfigurado para un
value_type
no especificado) e inicializa el objeto con los argumentos proporcionados. Retorna un objeto
std::shared_ptr
que gestiona el objeto recién creado.
T
, y se construye como si mediante
std::
allocator_traits
<
Alloc
>
::
construct
( a, pt, ( std:: forward < Args > ( args ) ... ) , donde pt es un std:: remove_cv_t < T > * puntero a almacenamiento adecuado para contener un objeto de tipo std:: remove_cv_t < T > . Si el objeto debe ser destruido, se destruye como si mediante std:: allocator_traits < Alloc > :: destroy ( a, pt ) , donde pt es un puntero a ese objeto de tipo std:: remove_cv_t < T > .
Alloc
, y es una copia potencialmente reenlazada de
alloc
.
|
Esta sobrecarga participa en la resolución de sobrecarga solo si
|
(since C++20) |
T
es un tipo de array sin límite.
T
. Cada elemento tiene un valor inicial predeterminado.
T
es un tipo de array acotado.
T
es un tipo de array sin límite.
T
. Cada elemento tiene el valor inicial
u
.
T
es un tipo de array acotado.
T
.
-
Si
Tno es un tipo de arreglo, el objeto se construye como si fuera mediante :: new ( pv ) T , donde pv es un puntero void * a almacenamiento adecuado para contener un objeto de tipoT. Si el objeto debe ser destruido, se destruye como si fuera mediante pt - > ~T ( ) , donde pt es un puntero a ese objeto de tipoT. -
Si
Tes un tipo de arreglo con límites definidos, el valor inicial no está especificado para cada elemento.
T
no es un tipo de array o es un tipo de array con límites definidos.
T
es un tipo de matriz sin límite.
Inicialización y destrucción de elementos de array
En la descripción a continuación,
a
es de tipo
Los elementos de array de tipo
2,3)
std::
allocator_traits
<
Alloc
>
::
construct
(
a, pu
)
4,5)
std::
allocator_traits
<
Alloc
>
::
construct
(
a, pu, u
)
6,7)
::
new
(
pv
)
U
Cuando finaliza el tiempo de vida del objeto gestionado por el std::shared_ptr retornado, o cuando la inicialización de un elemento de array lanza una excepción, los elementos inicializados se destruyen en el orden inverso a su construcción original.
Para cada elemento de array de tipo no-array
2-5)
std::
allocator_traits
<
Alloc
>
::
destroy
(
a, pu
)
, donde
pu
es un puntero
U
*
a ese elemento de array de tipo
U
6,7)
pu
-
>
~U
(
)
, donde
pu
es un puntero a ese elemento de array de tipo
U
|
(desde C++20) |
Parámetros
| alloc | - | el Allocator a utilizar |
| args... | - |
lista de argumentos con los cuales se construirá una instancia de
T
|
| N | - | tamaño del array a utilizar |
| u | - | el valor inicial para inicializar cada elemento del array |
Valor de retorno
std::shared_ptr
a un objeto de tipo
T
o
std::
remove_extent_t
<
T
>
[
N
]
si
T
es un tipo de array sin límite
(desde C++20)
.
Para el std::shared_ptr r devuelto, r. get ( ) retorna un puntero no nulo y r. use_count ( ) retorna 1 .
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 del array, los elementos ya inicializados se destruyen en orden inverso
(since C++20)
.
Notas
Estas funciones normalmente asignarán más memoria que sizeof ( T ) para permitir estructuras internas de contabilidad como conteos de referencia.
Al igual que
std::make_shared
, esta función normalmente 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, todas las implementaciones conocidas lo hacen). Una copia de
alloc
se almacena como parte del bloque de control para que pueda usarse para desasignarlo una vez que tanto los contadores de referencia compartidos como débiles lleguen a cero.
A diferencia de los
std::shared_ptr
constructors
,
std::allocate_shared
no acepta un deleter personalizado separado: el asignador proporcionado se utiliza para la destrucción del bloque de control y del objeto
T
, y para la desasignación de su bloque de memoria compartida.
|
std::shared_ptr
admite tipos de array (desde C++17), pero
|
(hasta C++20) |
Un constructor
habilita
shared_from_this
con un puntero
ptr
de tipo
U*
significa que determina si
U
tiene una clase base
inequívoca y accesible
(desde C++17)
que sea una especialización de
std::enable_shared_from_this
, y si es así, el constructor evalúa
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
)
)
;
.
La asignación a
weak_this
no es atómica y entra en conflicto con cualquier acceso concurrente potencial al mismo objeto. Esto garantiza que futuras llamadas a
shared_from_this()
compartirían la propiedad con el
std::shared_ptr
creado por este constructor de puntero en bruto.
La prueba
ptr
-
>
weak_this
.
expired
(
)
en el código anterior asegura que
weak_this
no sea reasignado si ya indica un propietario. Esta prueba es requerida a partir de C++17.
| Macro de prueba de características | Valor | Std | Característica |
|---|---|---|---|
__cpp_lib_smart_ptr_for_overwrite
|
202002L
|
(C++20) |
Creación de punteros inteligentes con inicialización por defecto (
std::allocate_shared_for_overwrite
,
std::make_shared_for_overwrite
,
std::make_unique_for_overwrite
); sobrecargas
(
6,7
)
|
Ejemplo
#include <cstddef> #include <iostream> #include <memory> #include <memory_resource> #include <vector> class Value { int i; public: Value(int i) : i(i) { std::cout << "Value(), i = " << i << '\n'; } ~Value() { std::cout << "~Value(), i = " << i << '\n'; } void print() const { std::cout << "i = " << i << '\n'; } }; int main() { // Crear un asignador polimórfico usando el recurso de búfer monótono std::byte buffer[sizeof(Value) * 8]; std::pmr::monotonic_buffer_resource resource(buffer, sizeof(buffer)); std::pmr::polymorphic_allocator<Value> allocator(&resource); std::vector<std::shared_ptr<Value>> v; for (int i{}; i != 4; ++i) // Usar std::allocate_shared con el asignador personalizado v.emplace_back(std::allocate_shared<Value>(allocator, i)); for (const auto& sp : v) sp->print(); } //< Todos los shared pointers limpiarán automáticamente cuando salgan del ámbito.
Salida:
Value(), i = 0 Value(), i = 1 Value(), i = 2 Value(), i = 3 i = 0 i = 1 i = 2 i = 3 ~Value(), i = 0 ~Value(), i = 1 ~Value(), i = 2 ~Value(), i = 3
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a estándares publicados anteriormente de C++.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 3216 | C++20 |
std::allocate_shared
siempre reenlazaba el
asignador antes de construir y destruir objetos |
el reenlace es opcional |
| LWG 4024 | C++20 |
no estaba claro cómo se destruyen los objetos construidos en
std::allocate_shared_for_overwrite
|
aclarado |
Véase también
construye un nuevo
shared_ptr
(función miembro pública) |
|
|
crea un puntero compartido que gestiona un nuevo objeto
(plantilla de función) |