Enable_shared_from_this deben ser la primera clase base?

Philip:

Mi clase hereda de múltiples bases, uno de los cuales es std::enable_shared_from_this. ¿Tiene que ser la primera base?

Supongamos que el ejemplo de código siguiente:

struct A { ~A(); };
struct B { ~B(); };
struct C : A, B, std::enable_shared_from_this<C> {};

std::make_shared<C>(); 

Cuando ~A()y ~B()correr, puedo estar seguro de que el almacenamiento donde Cvivía todavía está presente?

curiousguy:

Cuando ~A()y ~B()correr, puedo estar seguro de que el almacenamiento donde Cvivía todavía está presente?

¡Por supuesto! Sería difícil de usar una clase base que intenta liberar a su propia memoria (la memoria donde reside). No estoy seguro de que es incluso formalmente legal.

Implementaciones no hacen eso: cuando una shared_ptr<T>se destruye o RESET, el contador de referencia (RC) para la propiedad compartida de Tse decrementa (atómicamente); si llega a 0 en el valor de reducción, a continuación, la destrucción / eliminación de Tse inicia.

A continuación, los débiles-propietarios-o-T-exists se decrementa la cuenta (atómicamente), que Tya no existe: lo que necesitamos saber si somos la última entidad de pie interesado en el bloque de control; si el decremento dio un resultado distinto de cero, significa que algunos weak_ptrexisten que Compartir (podría ser 1 compartir, o 100%) la propiedad del bloque de control, y que ahora son responsables de la desasignación.

De cualquier manera, decremento atómica en algún momento terminar con un valor cero, para el último copropietario.

Aquí no hay hilos, sin no determinismo, y, obviamente, la última weak_ptr<T>fue destruida durante la destrucción de C. (La suposición no escrita en su pregunta es que ningún otro weak_ptr<T>se mantuvo.)

Destrucción siempre sucede en esa exacta orden. El bloque de control se utiliza para la destrucción, ya que no shared_ptr<T>sabe (en general) que destructor (potencialmente no virtual) de (potencialmente diferente) clase más derivada a la llamada . (El bloque de control también sabe no para liberar memoria compartida en el recuento de llegar a cero para make_shared.)

La variación sólo es práctico entre las implementaciones parece ser acerca de los detalles finos de las cercas de memoria y evitar algunas operaciones atómicas en los casos comunes.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=370052&siteId=1
Recomendado
Clasificación