vectores punteros programacion new matrices llenar funciones ejemplos dinamico con como clase c++ destructor

punteros - vectores en c++ pdf



Destructores C++ con vectores, punteros, (7)

Si tengo algo como std :: vector, ¿qué sucede cuando se llama al vector destructor?

Depende.

Si tiene un vector de valores std::vector <MyClass> , el destructor del vector llama al destructor para cada instancia de MyClass en el vector.

Si tiene un vector de punteros std::vector <MyClass*> , entonces es responsable de eliminar las instancias de MyClass .

¿Qué sucede si tengo un puntero a otra clase dentro de una clase?

ClassB instancia de ClassB permanecería en la memoria. Las posibles formas de tener ClassA destructor ClassA para hacer el trabajo para usted son hacer que B un miembro de instancia o un puntero inteligente.

Por lo que sé, debería destruir en destructores todo lo que creé con secuencias de archivos new y cerradas y otras transmisiones. Sin embargo, tengo algunas dudas sobre otros objetos en C ++:

  • std::vector y std::string s: ¿Se destruyen automáticamente?

  • Si tengo algo como

    std::vector<myClass*>

    De punteros a clases. ¿Qué pasa cuando se llama el vector destructor?
    ¿ myClass automáticamente al destructor de myClass ? ¿O solo se destruye el vector pero todos los objetos que contiene siguen existiendo en la memoria?

  • ¿Qué sucede si tengo un puntero a otra clase dentro de una clase, por ejemplo:

    class A { ClassB* B; }

    y la clase A se destruye en algún punto del código. ¿Se destruirá también la Clase B o solo el puntero y la Clase B seguirán existiendo en algún lugar de la memoria?


std :: vector y std :: strings: ¿Se destruyen automáticamente?

Sí (asumiendo que las variables miembro no son punteros a std::vector y std::string ).

Si tengo algo como std :: vector, ¿qué sucede cuando se llama al vector destructor? ¿Llamaría automáticamente al destructor de myClass? ¿O solo se destruye el vector pero todos los objetos que contiene siguen existiendo en la memoria?

Si el vector<MyClass> entonces todos los objetos contenidos en el vector serán destruidos. Si vector<MyClass*> , todos los objetos deben delete explícitamente d (suponiendo que la clase que se destruye posee los objetos en el vector ). Una tercera alternativa es el vector de punteros inteligentes, como vector<shared_ptr<MyClass>> , en cuyo caso los elementos del vector no necesitan ser delete explícitamente d.

¿Qué sucede si tengo un puntero a otra clase dentro de una clase?

La B debe ser delete explícitamente d. Una vez más, se podría usar un puntero inteligente para manejar la destrucción de B


  1. Sí. std::vector y std::string se ejecutan automáticamente cuando terminan fuera del alcance, y también llaman al destructor de los objetos contenidos (para std::vector ).

  2. Como se dijo antes, std::vector se destruye cuando termina fuera del alcance, llamando al destructor de los objetos contenidos. Pero, de hecho, en este caso, los objetos contenidos son los punteros, no el objeto apuntado por los punteros. Así que tienes que delete manualmente.

  3. Lo mismo que (2). A será destruido y por lo tanto el puntero, pero no la clase B señaló. Tienes que proporcionar un destructor para A que delete B.

En C ++ 11 hay una solución muy útil: use std::unique_pointer . Se puede usar solo para apuntar a un solo objeto y se eliminará cuando el puntero salga de su alcance (por ejemplo, cuando destruya su std::vector ).

http://en.cppreference.com/w/cpp/memory/unique_ptr


Depende. std::vector y std::string y MyClass tienen una cosa en común: si declara que una variable es cualquiera de esos tipos, se asignará en la pila, será local al bloque actual en el que se encuentra y Se destruirá cuando termine ese bloque.

P.ej

{ std::vector<std::string> a; std::string b; MyClass c; } //at this point, first c will be destroyed, then b, then all strings in a, then a.

Si llega a los punteros, lo adivinó correctamente: solo se liberará automáticamente la memoria que ocupa el propio puntero (generalmente un entero de 4 bytes) al salir del alcance. No le pasa nada a la memoria apuntada a menos que la delete explícitamente (ya sea en un vector o no). Si tiene una clase que contiene punteros a otros objetos, es posible que tenga que eliminarlos en el destructor (dependiendo de si esa clase posee o no esos objetos). Tenga en cuenta que en C ++ 11 hay clases de punteros (denominados punteros inteligentes) que le permiten tratar los punteros de forma similar a los objetos "normales":

Ex:

{ std::unique_ptr<std::string> a = make_unique<std::string>("Hello World"); function_that_wants_string_ptr(a.get()); } //here a will call delete on it''s internal string ptr and then be destroyed


Solo tiene que preocuparse por la memoria que ha creado dinámicamente (cuando reserva memoria con new ).

Por ejemplo:

Class Myclass{ private: char* ptr; public: ~Myclass() {delete[] ptr;}; }


std::vector , std::string y hasta donde sé, todos los otros contenedores STL tienen destructores automáticos. Esta es la razón por la que a menudo es mejor usar estos contenedores en lugar de new y delete ya que evitará las pérdidas de memoria.

myClass se myClass su myClass destructor si su vector es un vector de objetos myClass ( std::vector< myClass > ) en lugar de un vector de punteros a objetos myClass ( std::vector< myClass* > ).

En el primer caso, el destructor de std::vector también llamará al destructor de myClass para cada uno de sus elementos; en el segundo caso, el destructor de std::vector llamará al destructor de myClass* , lo que significa que liberará el espacio myClass* para almacenar cada puntero, pero no liberará el espacio myClass para almacenar los myClass objetos myClass .

Los objetos de Class B que apunta no se destruirán, pero el espacio asignado para almacenar su puntero se liberará.


  • Si están en almacenamiento automático, sí. Puede tener std::string* s = new std::string , en cuyo caso debe eliminarlo usted mismo.

  • nada, necesita eliminar manualmente la memoria que posee (para la memoria asignada con new ).

  • Si asignó b con new , debería destruirlo explícitamente en el destructor.

Una buena regla empírica es utilizar delete/delete[] para cada new/new[] que tenga en su código.

Una mejor regla de oro es usar RAII y usar punteros inteligentes en lugar de punteros sin procesar.