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
ystd::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 demyClass
? ¿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
Sí.
std::vector
ystd::string
se ejecutan automáticamente cuando terminan fuera del alcance, y también llaman al destructor de los objetos contenidos (parastd::vector
).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 quedelete
manualmente.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
).
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
connew
, 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.