Un ejemplo. Teniendo la siguiente clase Acumulador:
#include <cstdio>Un código como el siguiente:
class Acumulador {
int v;
public:
Acumulador() { v = 0; }
~Acumulador() { std::printf("%d\n", v); }
void acumular(int x) { v += x; }
};
{Al compilarlo (optimizándolo), el código equivale a exactamente esto:
Acumulador acum;
acum.acumular(2);
acum.acumular(4);
acum.acumular(10);
}
{La clase Acumulador ya no existe. Obtenemos el código más óptimo posible: sin llamadas a la función "acumular", ni ningún byte extra de memoria (Acumulador ocupa lo mismo de memoria que ocupa un "int").
int v = 0;
v += 2;
v += 4;
v += 10;
std::printf("%d\n", v);
}
Este ejemplo no ayuda a ver grandes ventajas, pero si el constructor y el destructor hacen tareas complicadas, y las funciones miembros también, el resultado puede llevarnos a dos puntos:
- Nos abstrae de la complejidad de la implementación (e.j. para qué quiero saber cómo se acumula si sólo quiero acumular)
- Obtenemos código tan óptimo como si no hubiéramos usado la abstracción (e.j. las operaciones se acercan al hardware tanto como sea posible).