Puntero inteligente de C ++ compartido_ptr / débil_ptr

Después de familiarizarnos con unique_ptr, descubrimos que la gestión de memoria exclusiva de unique_ptr no es adecuada para todas las situaciones y tiene grandes limitaciones. ¿Qué sucede si necesita compartir varias variables de puntero?

Si hay una forma de registrar el número de punteros inteligentes que se refieren a un objeto de memoria específico, al copiar o copiar, el recuento de referencias aumenta en 1, cuando se destruye el puntero inteligente,

El recuento de referencia se reduce en 1. Si el recuento es cero, significa que no hay un puntero a esta memoria, ¡entonces lo liberamos! ¡Esta es la estrategia adoptada por shared_ptr!

Constructor

shared_ptr <T> sp; // Empty shared_ptr, que puede apuntar a un objeto de tipo T

shared_ptr <T> sp1 (new T ()); // define shared_ptr y apunta a un objeto de tipo T

shared_ptr <T []> sp2; // Shared_ptr vacío, que puede apuntar a un objeto de matriz de tipo T [ Compatible después de C ++ 17 

shared_ptr <T []> sp3 (new T [] {...}); // apunta a un objeto de matriz de tipo T , compatible después de C ++ 17 

shared_ptr <T> sp4 (NULL, D ());  // Vacía shared_ptr, acepta un eliminador de tipo D, usa D

Liberar memoria

shared_ptr <T> sp5 (new T (), D ()); // Defina shared_ptr, apunte a un objeto de tipo T, acepte un borrador D y use el borrador D  para liberar memoria      

 

inicialización

Método uno constructor

shared_ptrr <int> up1 (new int (10)); // int (10) tiene un recuento de referencias de 1

shared_ptrr <int> up2 (up1); // Use el puntero inteligente up1 para construir up2, en este momento el recuento de referencias int (10) es 2

 

El segundo método usa make_shared para inicializar el objeto, que es más eficiente en la asignación de memoria.

La función principal de la función make_shared es asignar un objeto en la memoria dinámica, inicializarlo y devolver un shared_ptr que apunta a este objeto; uso:

make_shared < tipo > ( lista de parámetros necesarios para construir un objeto de tipo ) ;

shared_ptr <int> p4 = make_shared <int> (2); // Varios parámetros están separados por comas ',' y se aceptan hasta diez

shared_ptr <cadena> p4 = make_shared <cadena> ("字符串");

 

Asignación

shared_ptr <int> up1 (new int (10)); // int (10) tiene un recuento de referencias de 1

shared_ptr <int> up2 (new int (11)); // int (11) tiene un recuento de referencias de 1

up1 = up2; // El recuento de referencia de int (10) se reduce en 1, el recuento se restablece a cero y la memoria se libera, y up2 comparte int (11) con up1, int (11)

Tiene un recuento de referencias de 2

 

Liberar objetos de forma activa

shared_ptrr <int> up1 (nuevo int (10));

up1 = nullptr; // El recuento de referencia de int (10) se reduce en 1, el recuento se restablece a cero y la memoria se libera 

o

up1 = NULL; // Igual que arriba 

 

Reiniciar

up.reset (); // Restablecer p a un puntero nulo y disminuir el recuento de referencia del objeto administrado en 1

up.reset (p1); // Restablecer p a p1 (el valor de), disminuir el recuento de objetos controlados por p, y p toma el control del puntero de p1

up.reset (p1, d); // Restablecer p ap ( el valor de), disminuir el recuento de objetos controlados por p en 1 y usar d como el borrador

 

intercambiar

std :: swap (p1, p2); // Intercambia los objetos administrados por p1 y p2, el recuento de referencias del objeto original permanece sin cambios

p1.swap (p2); // Igual que el anterior

 

La trampa de shared_ptr [Referencia cruzada]

#include <stdio.h>
#include <iostream>
#include <string>
#include <memory>
#include <vector>

using namespace std;

class girl;

class boy {
public:
    boy() {
        cout << "boy construct!" << endl;
    }

    ~boy() {
        cout << "boy destruct!" << endl;
    }

    void set_girl_friend(shared_ptr<girl> &g) {
        girl_friend = g;
    }
private:
    shared_ptr<girl> girl_friend;
};

class girl {
public:
    girl() {
        cout << "girl construct!" << endl;
    }

    ~girl() {
        cout << "girl destruct!" << endl;
    }

    void set_boy_friend(shared_ptr<boy> &b) {
        boy_friend = b;
    }
private:
    shared_ptr<boy> boy_friend;
};


void use_trap() {
    shared_ptr<girl> sp_girl(new girl());//白娘子
    shared_ptr<boy> sp_boy(new boy());  //许仙

    sp_girl->set_boy_friend(sp_boy);
    sp_boy->set_girl_friend(sp_girl);

} // 函数退出之后 引用计数都是从2->1并没有变成0 所以没有调用析构函数,就会造成资源的泄漏
// weak_ptr 弱指针就可以 不该变引用技术

int main() {

	use_trap();
	system("pause");
	return 0;
}

6 . 5 uso weak_ptr Comentarios (desde C ++ 11) 

    El propósito del diseño de débil_ptr es introducir un puntero inteligente para ayudar a shared_ptr con shared_ptr. Solo se puede construir a partir de un objeto shared_ptr u otro objeto débil_ptr, y su construcción y destrucción no provocará un aumento o disminución en el recuento de referencias. Al mismo tiempo, débil_ptr no tiene sobrecarga * y ->, pero puede usar el bloqueo para obtener un objeto compartido_ptr utilizable.

Siempre que el miembro de una de las clases anteriores se cambie a debil_ptr <chica> o debil_ptr <chico>, no habrá errores.

 

 

 

 

 

 

Supongo que te gusta

Origin blog.csdn.net/qq_44065088/article/details/109198406
Recomendado
Clasificación