RAII, copia y movimiento
Objetos dueños de memoria: el destructor que libera, copiar sin compartir, la regla de 3, de 5 y de 0, y mover en vez de copiar.
13 aulas · 11 horas de práctica · en el navegador, sin instalar nada
Temario
- El problema: copiar una clase que tiene un new — Copiar un objeto copia sus campos, y un campo puntero se copia como flecha: dos objetos terminan con la misma caja del heap, y los dos la devuelven. Cómo se ve, por qué rompe, y cómo esquivarlo con lo que ya sabés.
- RAII: el destructor libera — La idea más importante de C++: un objeto de la pila es dueño de un recurso, lo pide al nacer y lo devuelve al morir. Como el destructor corre siempre, por cualquier salida, no hay delete que olvidar.
- Constructor de copia — Enseñarle a una clase a copiarse: el constructor que recibe otro objeto de la misma clase y arma una caja nueva con lo mismo adentro. Cuándo corre, por qué recibe const&, y por qué, una vez que lo escribís, lo tenés que copiar todo.
- Asignación y copy-and-swap — La asignación copia sobre un objeto que ya existe, y por eso tiene que devolver primero lo que tenía. El operator= clásico, la trampa de asignarse a sí mismo, y copy-and-swap: la forma corta que no puede equivocarse.
- La regla de 3 — Destructor, constructor de copia y asignación: si una clase necesita escribir uno, necesita los tres. Una revisión que prueba a cada integrante y la rueda que ilumina al que falta.
- lvalues y rvalues — Algunos valores tienen nombre y siguen vivos; otros son temporales que mueren al terminar la línea. A un temporal se le puede robar la caja en vez de copiarla: para eso existe &&. Y std::move, que no mueve nada.
- Constructor de movimiento — El robo del aula anterior, hecho constructor: el objeto nuevo se queda con la caja del otro y lo deja vacío. La flecha cambia de dueño sin ningún new. Y por qué noexcept hace que un vector que crece mueva en vez de copiar.
- std::move — Cuándo pedir un movimiento a mano: pasar algo que no vas a usar más, cargar un contenedor, intercambiar. Qué queda en lo movido, por qué const no se mueve, y la carrera entre copias y movimientos.
- Reglas de 5 y de 0 — Con el movimiento, los tres de la regla de 3 pasan a ser cinco. Qué escribe C++ solo y qué borra cuando escribís uno. Y la regla que más se usa en la práctica: si tus campos ya se manejan solos, no escribas ninguno.
- = delete y = default: objetos que no se copian — Algunas cosas no se deben copiar: una llave única, una conexión, una sala. Con = delete la copia no compila; con = default le pedís a C++ la versión que escribe solo. Y los tipos que solo se mueven.
- Copy elision y RVO — Devolver un objeto por valor no lo copia ni lo mueve: el compilador lo construye directo donde va. Cuándo pasa (RVO y NRVO), cómo se rompe (return std::move, dos variables, el ternario) y por qué ya no hace falta devolver punteros "para no copiar".
- Tu propio std::string — Un string de verdad, desde cero: los caracteres en el heap con su \0, y los cinco miembros especiales uno por uno. Al final, una cadena que se copia, se asigna, se mueve y crece sin perder ni una caja.
- Buffer de audio sin copias — Una mezcla en vivo, donde copiar un buffer es llegar tarde. Pistas dueñas de sus pasos que entran al escenario moviéndose, un eco que sí es una copia, y un cambio de pista en pleno show.