C++ se compila a código máquina y da un control muy fino sobre la memoria, por eso se usa donde el rendimiento importa: motores de videojuegos, navegadores, programas de edición, bases de datos o sistemas embebidos. Es más exigente que otros lenguajes, pero sus herramientas modernas (C++11 en adelante) lo hacen mucho más seguro.
Videojuegos y motores gráficos
Programas de alto rendimiento
Sistemas y dispositivos
Para empezar: Instala un compilador (GCC, Clang o Visual Studio con C++) y compila cada ejemplo con g++ -std=c++20 main.cpp -o main.
Nivel 1 Básico
1
Lección 1 · Básico
Tu primer programa
Un programa en C++ empieza en la función main. #include <iostream> trae la parte de la biblioteca estándar que permite escribir en la consola con std::cout y el operador <<.
El compilador traduce el archivo .cpp a un ejecutable. Si cambias el código, hay que volver a compilar.
Respuesta:cout. std::cout es la salida estándar; con << le envías lo que quieres mostrar.
2
Lección 2 · Básico
Variables y tipos
Cada variable tiene un tipo fijo: int, double, bool, char o std::string para texto (con #include <string>). Con auto, el compilador deduce el tipo del valor.
Inicializa siempre las variables: en C++ una variable local sin valor inicial contiene basura.
Ejemplo práctico
#include <iostream>
#include <string>
int main() {
int unidades = 3;
double precio = 19.99;
std::string producto = "Auriculares";
auto total = unidades * precio; // double
std::cout << producto << ": " << total << '\n';
}
Ejercicio
¿Qué hace auto en auto total = unidades * precio;?
Ver la solución
Respuesta: El compilador deduce el tipo del valor. auto deduce el tipo en tiempo de compilación; la variable sigue teniendo un tipo fijo (aquí, double).
3
Lección 3 · Básico
Condiciones y bucles
if y else deciden qué se ejecuta; for repite con un contador y while mientras se cumpla una condición. Los bloques van entre llaves.
Las comparaciones usan ==, !=, <, >, <= y >=, y se combinan con && (y) y || (o).
Ejemplo práctico
#include <iostream>
int main() {
for (int i = 1; i <= 5; ++i) {
if (i % 2 == 0) {
std::cout << i << " es par\n";
} else {
std::cout << i << " es impar\n";
}
}
}
Ejercicio
¿Qué calcula i % 2?
Ver la solución
Respuesta: El resto de dividir i entre 2. % es el resto de la división: vale 0 si el número es par.
4
Lección 4 · Básico
std::vector: listas que crecen
std::vector es la lista dinámica de la biblioteca estándar: crece al añadir elementos con push_back y size() dice cuántos tiene.
El bucle for basado en rango recorre todos los elementos sin manejar posiciones.
Ejemplo práctico
#include <iostream>
#include <vector>
int main() {
std::vector<int> notas = {7, 8, 9};
notas.push_back(10);
int suma = 0;
for (int n : notas) suma += n;
std::cout << "Media: " << static_cast<double>(suma) / notas.size() << '\n'; // 8.5
}
Ejercicio
Completa para añadir un 6 al final del vector.
notas.(6);
Ver la solución
Respuesta:push_back. push_back añade un elemento al final del vector.
Nivel 2 Intermedio
5
Lección 5 · Intermedio
Funciones y referencias
Una función declara el tipo que devuelve, su nombre y sus parámetros. Por defecto los argumentos se copian; con una referencia (&) la función trabaja con la variable original.
Para objetos grandes que no vas a modificar, pásalos como const&: no se copian y tampoco se pueden cambiar.
Ejemplo práctico
#include <iostream>
#include <string>
void duplicar(int& n) { n *= 2; } // modifica el original
std::string saludo(const std::string& nombre) { // sin copia ni cambios
return "Hola, " + nombre;
}
int main() {
int x = 5;
duplicar(x);
std::cout << x << '\n'; // 10
std::cout << saludo("Ana") << '\n';
}
Ejercicio
¿Qué ocurre con void duplicar(int& n) al llamar duplicar(x)?
Ver la solución
Respuesta: x cambia, porque se pasa por referencia. Con & el parámetro es otro nombre para la misma variable, así que el cambio se ve fuera.
6
Lección 6 · Intermedio
Clases
Una clase agrupa datos y funciones. Lo que está en private solo se puede usar desde dentro; lo que está en public, desde cualquier parte.
El constructor prepara el objeto al crearlo; con la lista de inicialización (: saldo_(inicial)) das valor a los atributos.
Respuesta: Solo desde dentro de la propia clase. private oculta el miembro: solo los métodos de la clase pueden usarlo.
7
Lección 7 · Intermedio
La biblioteca estándar: algoritmos y map
La biblioteca estándar trae contenedores como std::map (pares clave–valor ordenados por clave) y algoritmos listos para usar en <algorithm>, como std::sort o std::count_if.
Antes de escribir tu propio bucle para ordenar o buscar, mira si ya existe un algoritmo: será correcto y eficiente.
Respuesta:sort. std::sort ordena el rango entre los dos iteradores que le pases.
Nivel 3 Avanzado
8
Lección 8 · Avanzado
Memoria y punteros inteligentes
Un puntero guarda la dirección de memoria de otro dato. Reservar memoria con new obliga a liberarla con delete, y olvidarlo provoca fugas o fallos graves.
En C++ moderno se usan punteros inteligentes: std::unique_ptr libera la memoria solo cuando deja de usarse (RAII). Así no hace falta escribir delete.
¿Qué ventaja tiene std::unique_ptr frente a new y delete?
Ver la solución
Respuesta: Libera la memoria automáticamente. Cuando el unique_ptr sale de su ámbito, su destructor libera la memoria: no puedes olvidarte de hacerlo.
9
Lección 9 · Avanzado
Plantillas
Una plantilla (template) es código genérico: escribes la función una vez y el compilador genera una versión para cada tipo con el que la uses.
Toda la biblioteca estándar está hecha con plantillas: std::vector<int> y std::vector<std::string> salen del mismo código.
Ejemplo práctico
#include <iostream>
#include <string>
template <typename T>
T mayor(T a, T b) {
return a > b ? a : b;
}
int main() {
std::cout << mayor(3, 7) << '\n'; // 7
std::cout << mayor(std::string("pera"), std::string("kiwi")) << '\n'; // pera
}
Ejercicio
¿Qué hace el compilador con template <typename T>?
Ver la solución
Respuesta: Crea una versión de la función para cada tipo usado. Cada vez que usas la plantilla con un tipo nuevo, el compilador genera el código para ese tipo.
10
Lección 10 · Avanzado
Herencia y polimorfismo
Una clase puede heredar de otra y redefinir sus métodos virtual con override. Así, una lista de punteros a la clase base puede contener objetos distintos y cada uno responde a su manera.
Una clase base con métodos virtuales debe tener un destructor virtual para que los objetos se destruyan bien.
Completa la palabra que indica que el método redefine uno de la clase base.
double area() const { return lado * lado; }
Ver la solución
Respuesta:override. override pide al compilador que compruebe que de verdad estás redefiniendo un método virtual.
¿Has terminado? Sigue practicando
Repasa los conceptos en el diccionario, practica con estas herramientas o prueba otro lenguaje: las ideas que has aprendido (variables, condiciones, funciones, objetos…) te servirán en cualquiera.
* Porcentaje de personas que dijeron haber usado C++ en la Stack Overflow Developer Survey 2026: Technology (pregunta sobre lenguajes de programación, de scripts y de marcado; todas las respuestas). El progreso de las lecciones se guarda solo en este navegador.
¿Nos dejas medir las visitas?
Con tu permiso usamos Google Analytics, que guarda cookies, para saber cuántas personas visitan la web y qué páginas les resultan útiles. No usamos cookies de publicidad y tus archivos nunca salen de tu navegador. Puedes cambiar de opinión cuando quieras en «Configurar cookies», al pie de la página. Más información.