Compartir a través de


Duración y administración de recursos (C++ moderno) del objeto

A diferencia de los lenguajes administrados, C++ no tiene garbage collection (GC), que automáticamente libera los recursos de memoria no-más utilizados mientras se ejecuta un programa.En C++, administración de recursos está directamente relacionado con duración de objetos.Este documento describe los factores que afectan a la duración de los objetos de C++ y cómo administrarlo.

C++ no tiene GC principalmente porque no administra los recursos de memoria que no.Sólo destructores deterministas como las de C++ pueden controlar los recursos de memoria y memoria que no sea igual.Catálogo global también tiene otros problemas, como una mayor sobrecarga de memoria y consumo de CPU y localidad.Pero la universalidad es un problema fundamental que no se pueden mitigar mediante optimizaciones inteligentes.

Conceptos

Una cosa importante en administración de la duración del objeto es la encapsulación, gana el jugador que está utilizando un objeto no tiene que saber lo que posee los recursos de ese objeto, o cómo deshacerse de ellos o incluso si posee todos los recursos en todo.Sólo tiene que destruir el objeto.El núcleo del lenguaje C++ está diseñado para garantizar que los objetos se destruyen en el momento adecuado, es decir, como los bloques son salir, en orden inverso de construcción.Cuando se destruye un objeto, se destruyen sus bases y los miembros en un orden determinado.El idioma automáticamente destruye los objetos, a menos que hacer cosas especiales como asignación del montón o la ubicación nueva.Por ejemplo, punteros inteligentes como unique_ptr y shared_ptr, y como contenedores de la biblioteca de plantillas estándar (STL) vector, encapsular new/delete y new[]/delete[] en objetos, que tienen destructores.Por eso es tan importante utilizar punteros inteligentes y los contenedores STL.

Otro concepto importante en la administración de la duración: los destructores.Los destructores encapsulan liberar el recurso.(La tecla de acceso frecuente es RRID, destrucción de es de liberación de recursos). Un recurso es algo que obtener del "sistema" y tiene que devolver más adelante.La memoria es el recurso más comunes, pero también son archivos, sockets, texturas y otros recursos de memoria que no. "Propiedad"de un recurso: puede utilizar cuando lo necesite, pero también debe liberarla cuando haya terminado con él.Cuando se destruye un objeto, su destructor libera los recursos que un propietario.

El concepto final es DAG (gráfico acíclico dirigido).La estructura de la propiedad en un programa de forma un DAG.No hay ningún objeto puede ser propietario de sí mismo, que no sólo es imposible, pero también inherentemente sin sentido.Pero dos objetos pueden compartir la propiedad de un tercer objeto.Varios tipos de vínculos son posibles en un DAG como este: A es un miembro de B (B posee una), almacenes c un vector<D> (C posee cada elemento D), almacenes e un shared_ptr<F> (E comparte posesión de F, posiblemente con otros objetos), y así sucesivamente.Siempre y cuando no hay ningún ciclos y todos los vínculos del DAG está representado por un objeto que tiene un destructor (en lugar de un puntero sin formato, identificador o otro mecanismo) y, a continuación, pérdidas de recursos son imposibles porque impide que el idioma de ellos.Los recursos se liberan inmediatamente después de que ya no sea necesario, sin un recolector de elementos no utilizados que ejecutan.El período de duración de seguimiento es gratis overhead para ámbito de la pila, bases, miembros y relacionados de los casos y bajo costo para shared_ptr.

Hh438473.collapse_all(es-es,VS.110).gifDuración basada en el montón

Para la duración de objetos del montón, utilice punteros inteligentes.Uso shared_ptr y make_shared como el puntero por defecto y el asignador.Uso weak_ptr para romper los ciclos, hacer el almacenamiento en caché y observar objetos sin afectar ni suponiendo que nada acerca de su período de duración.

void func() {

auto p = make_shared<widget>(); // no leak, and exception safe
...
p->draw(); 

} // no delete required, out-of-scope triggers smart pointer destructor

Uso unique_ptr para la propiedad única, por ejemplo, en el pimpl idiom.(Vea Pimpl para la encapsulación de tiempo de compilación (C++ moderno).) Hacer un unique_ptr el objetivo principal de todos explícitos new las expresiones.

unique_ptr<widget> p(new widget());

Puede utilizar punteros sin procesar para que no sean de propiedad y de observación.Puede colgar un puntero no propietaria, pero no se puede perder.

class node {
  ...
  vector<unique_ptr<node>> children; // node owns children
  node* parent; // node observes parent, which is not a concern
  ...
};
node::node() : parent(...) { children.emplace_back(new node(...) ); }

Cuando se requiere la optimización del rendimiento, es posible que deba utilizar encapsulado propietario de punteros y las llamadas explícitas a eliminar.Por ejemplo, cuando implemente su propia estructura de datos de bajo nivel.

Hh438473.collapse_all(es-es,VS.110).gifDuración basada en la pila

En C++ moderno, alcance basado en pila es una poderosa manera de escribir código robusto, ya que combina automática duración de la pila y duración de miembro de datos con alta eficiencia: duración de seguimiento es esencialmente gratuita de sobrecarga.Duración de objetos de montón requiere administración manual diligente y puede ser la fuente de pérdidas de recursos y la ineficacia, especialmente cuando se trabaja con punteros sin procesar.Tenga en cuenta este código, que se muestra alcance basado en la pila:

class widget {
private:
  gadget g;   // lifetime automatically tied to enclosing object
public:
  void draw();
};

void functionUsingWidget () {
  widget w;   // lifetime automatically tied to enclosing scope
              // constructs w, including the w.g gadget member
  …
  w.draw();
  …
} // automatic destruction and deallocation for w and w.g
  // automatic exception safety, 
  // as if "finally { w.dispose(); w.g.dispose(); }"

Utilizar con moderación de período de duración estática (static global, local estática de función) ya que pueden surgir problemas.¿Qué ocurre cuando el constructor de un objeto global produce una excepción?Normalmente, los errores de aplicación de modo que puede ser difícil de depurar.Orden de construcción es problemática para los objetos de período de duración estática y no es seguro para la ejecución de simultaneidad.No sólo es un problema de construcción de objetos orden de destrucción puede ser compleja, especialmente cuando se trate de polimorfismo.Incluso si el objeto o variable no es polimórfico y no tiene compleja Construcción/destrucción de pedidos, sigue siendo el problema de simultaneidad de subprocesos.Una aplicación multiproceso no puede modificar con seguridad los datos en objetos estáticos sin necesidad de almacenamiento local de subprocesos, bloqueos de recursos y otras precauciones especiales.

Vea también

Otros recursos

Bienvenido a C++ (C++ moderno)

Referencia del lenguaje C++

Referencia de la biblioteca estándar de C++