std:: enable_shared_from_this
|
Definido en el encabezado
<memory>
|
||
|
template
<
class
T
>
class enable_shared_from_this ; |
(desde C++11) | |
std::enable_shared_from_this
permite que un objeto
t
que está actualmente gestionado por un
std::shared_ptr
llamado
pt
pueda generar de forma segura instancias adicionales de
std::shared_ptr
como
pt1
,
pt2
etc., que compartan la propiedad de
t
con
pt
.
Heredar públicamente de
std::enable_shared_from_this<T>
proporciona al tipo
T
una función miembro
shared_from_this
. Si un objeto
t
de tipo
T
está gestionado por un
std::
shared_ptr
<
T
>
llamado
pt
, entonces llamar a
T::shared_from_this
devolverá un nuevo
std::
shared_ptr
<
T
>
que comparte la propiedad de
t
con
pt
.
ContenidoMiembros de datos
Funciones miembro
NotasLos constructores de std::shared_ptr detectan la presencia de una base inequívoca y accesible (es decir, pública) Llamar a
Ejemplo
Ejecutar este código
#include <iostream> #include <memory> class Good : public std::enable_shared_from_this<Good> { public: std::shared_ptr<Good> getptr() { return shared_from_this(); } }; class Best : public std::enable_shared_from_this<Best> { struct Private{ explicit Private() = default; }; public: // El constructor solo es utilizable por esta clase Best(Private) {} // Todos los demás deben usar esta función de fábrica // Por lo tanto, todos los objetos Best estarán contenidos en shared_ptr static std::shared_ptr<Best> create() { return std::make_shared<Best>(Private()); } std::shared_ptr<Best> getptr() { return shared_from_this(); } }; struct Bad { std::shared_ptr<Bad> getptr() { return std::shared_ptr<Bad>(this); } ~Bad() { std::cout << "Bad::~Bad() called\n"; } }; void testGood() { // Bueno: los dos shared_ptr comparten el mismo objeto std::shared_ptr<Good> good0 = std::make_shared<Good>(); std::shared_ptr<Good> good1 = good0->getptr(); std::cout << "good1.use_count() = " << good1.use_count() << '\n'; } void misuseGood() { // Malo: se llama a shared_from_this sin que std::shared_ptr sea propietario del llamador try { Good not_so_good; std::shared_ptr<Good> gp1 = not_so_good.getptr(); } catch (std::bad_weak_ptr& e) { // comportamiento indefinido (hasta C++17) y std::bad_weak_ptr lanzado (desde C++17) std::cout << e.what() << '\n'; } } void testBest() { // Mejor: Igual pero no se puede asignar en la pila: std::shared_ptr<Best> best0 = Best::create(); std::shared_ptr<Best> best1 = best0->getptr(); std::cout << "best1.use_count() = " << best1.use_count() << '\n'; // Best stackBest; // <- No compilará porque Best::Best() es privado. } void testBad() { // Malo: cada shared_ptr cree que es el único propietario del objeto std::shared_ptr<Bad> bad0 = std::make_shared<Bad>(); std::shared_ptr<Bad> bad1 = bad0->getptr(); std::cout << "bad1.use_count() = " << bad1.use_count() << '\n'; } // Comportamiento indefinido: doble eliminación de Bad int main() { testGood(); misuseGood(); testBest(); testBad(); } Salida posible: good1.use_count() = 2 bad_weak_ptr best1.use_count() = 2 bad1.use_count() = 1 Bad::~Bad() llamado Bad::~Bad() llamado *** glibc detectado *** ./test: doble liberación o corrupción Informes de defectosLos siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
Véase también
|