Es un lenguaje de programación de propósito general, orientado a objetos, y una extensión de C. Es ampliamente utilizado en el desarrollo de software de sistemas, aplicaciones y videojuegos.
Introducción a C++
Compilar un programa C++
Utiliza un compilador como g++ o clang++ para compilar archivos .cpp.
g++ programa.cpp -o programaEstructura básica de un programa
#include <iostream>
using namespace std;
int main() {
cout << "Hola, Mundo!" << endl;
return 0;
}Comentarios
Para escribir comentarios de una línea o múltiples líneas.
// Comentario de una sola línea
/*
Comentario de múltiples líneas
*/Namespaces
Los namespaces organizan código y evitan colisiones de nombres.
namespace MiEspacio {
int valor = 10;
}
cout << MiEspacio::valor;El más común es std.
using namespace std; // Evita tener que escribir std:: delante de cada función de la librería estándar.Módulos
Permiten dividir programas en módulos más gestionables y eficientes.
export module math;
export int suma(int a, int b) { return a + b; }Variables y tipos
Tipos primitivos
Los tipos básicos incluyen:
int: Enterosfloat: Números de coma flotantedouble: Números de doble precisiónchar: Caracteresbool: Booleanos (trueofalse)
Modificadores de tipos
Los modificadores amplían los tipos de datos primitivos.
short: Entero pequeñolong: Entero grandeunsigned: Sin signo (solo valores positivos)
Expresiones constantes
Permiten evaluar funciones o variables en tiempo de compilación.
constexpr int square(int x) { return x * x; }
constexpr int result = square(5); // Evaluado en tiempo de compilaciónDeclaración automática de tipos
Permite que el compilador deduzca el tipo de la variable.
auto x = 10; // x es de tipo int
auto y = 3.14; // y es de tipo doubleConstinit
Garantiza que una variable global sea inicializada en tiempo de compilación.
constinit int x = 42;Operadores
Operadores aritméticos
Suma (+), resta (-), multiplicación (*), división (/), módulo (%).
Operadores relacionales
Igualdad (==), desigualdad (!=), mayor (>), menor (<), mayor o igual (>=), menor o igual (<=).
Operadores lógicos
Y lógico (&&), O lógico (||), negación (!).
Operadores de asignación
Igual (=), suma-asignación (+=), resta-asignación (-=), etc.
Spaceship operator (<=>)
Permite realizar comparaciones completas.
#include <compare>
int a = 1, b = 2;
auto result = a <=> b;Entrada y Salida
Salida con cout
Muestra datos en la consola.
cout << "Valor: " << variable << endl;Entrada con cin
Captura datos del usuario.
int numero;
cin >> numero;Control de Flujo
Condicionales
If - Else
Evalúa una condición y ejecuta el código dependiendo del resultado.
if (condicion) {
// código si verdadero
} else {
// código si falso
}Switch
Estructura para manejar múltiples casos.
switch (valor) {
case 1:
// código para caso 1
break;
case 2:
// código para caso 2
break;
default:
// código para otros casos
}Bucles
Bucle For
Se utiliza para iteraciones controladas.
for (int i = 0; i < 10; i++) {
cout << i << endl;
}Bucle While
Repite mientras una condición es verdadera.
int i = 0;
while (i < 10) {
cout << i << endl;
i++;
}Bucle Do-While
Garantiza al menos una ejecución del bloque de código.
int i = 0;
do {
cout << i << endl;
i++;
} while (i < 10);Bucles for basados en rango
Facilitan la iteración sobre contenedores.
std::vector<int> vec = {1, 2, 3};
for (auto &v : vec) {
std::cout << v << std::endl;
}Funciones
Declaración de funciones
Una función recibe parámetros, realiza una tarea y opcionalmente devuelve un valor.
int sumar(int a, int b) {
return a + b;
}Prototipo de función
Declarar la función antes de main() y definirla después de main().
int sumar(int a, int b); // Prototipo
int main() {
cout << sumar(5, 3) << endl;
return 0;
}
int sumar(int a, int b) {
return a + b;
}Sobrecarga de funciones
Permite definir varias funciones con el mismo nombre, pero diferentes parámetros.
int suma(int a, int b) { return a + b; }
float suma(float a, float b) { return a + b; }Funciones con valores por defecto
int multiplicar(int a, int b = 2) {
return a * b;
}Funciones lambda
Permiten definir funciones anónimas en línea, muy útil para callbacks o para usar en algoritmos.
auto sum = [](int a, int b) { return a + b; };
std::cout << sum(5, 3); // Imprime 8Colecciones
Arrays
Declaración y acceso a arrays
int arr[5] = {1, 2, 3, 4, 5};
cout << arr[0]; // Imprime 1Contenedores STL
Contenedores comunes del STL (Standard Template Library)
- Vector: Arreglo dinámico.
- Map: Estructura de datos de clave-valor.
- Set: Conjunto de elementos únicos.
#include <vector>
#include <map>
#include <set>
std::vector<int> vec = {1, 2, 3};
std::map<int, std::string> mapa = {{1, "Uno"}, {2, "Dos"}};
std::set<int> conjunto = {1, 2, 3};Inicialización de listas
Permite inicializar contenedores o variables directamente usando llaves {}.
std::vector<int> vec = {1, 2, 3, 4, 5};
int arr[] = {1, 2, 3};Iteradores
Facilitan la navegación por contenedores.
std::vector<int> vec = {1, 2, 3};
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << std::endl;
}Rangos
Permiten operaciones más expresivas sobre contenedores.
#include <ranges>
std::vector<int> nums = {1, 2, 3, 4, 5};
auto even_nums = nums | std::ranges::views::filter([](int n) { return n % 2 == 0; });Punteros
Punteros
Un puntero almacena la dirección de una variable.
int x = 10;
int* p = &x; // p apunta a la dirección de x
cout << *p; // Imprime el valor de xUso de nullptr
Se usa en lugar de NULL para representar un puntero nulo de manera más segura.
int* p = nullptr; // Mejor que usar NULLPunteros inteligentes
Los punteros inteligentes como std::unique_ptr y std::shared_ptr gestionan la memoria automáticamente, evitando fugas de memoria.
#include <memory>
std::unique_ptr<int> ptr = std::make_unique<int>(10); // C++14 en adelante
std::shared_ptr<int> sharedPtr = std::make_shared<int>(20);Move semantics
Optimiza el rendimiento evitando copias innecesarias.
class MiClase {
public:
MiClase(const MiClase&) = delete; // Evita copias
MiClase(MiClase&&) = default; // Permite movimientos
};Referencias
Concepto de Referencias
Las referencias son alias para variables existentes. Permiten manipular el valor de la variable original sin crear una copia.
int original = 30;
int &ref = original; // ref es una referencia a original- Los cambios en la referencia afectan a la variable original.
- Las referencias son útiles para pasar grandes estructuras de datos a funciones sin hacer copias.
Manejo de Memoria Dinámica
new y delete
Se utilizan para reservar y liberar memoria en el heap.
int* p = new int; // Reserva memoria
*p = 10;
delete p; // Libera memoriaArrays dinámicos
int* arr = new int[5]; // Reserva un array
delete[] arr; // Libera el arrayClases y programación orientada a objetos
Definición de clase
Una clase es una plantilla para crear objetos.
class Persona {
public:
string nombre;
int edad;
void saludar() {
cout << "Hola, soy " << nombre << endl;
}
};Creación de objetos
Persona p;
p.nombre = "Luis";
p.edad = 25;
p.saludar();Constructor
Inicializa un objeto al crearlo.
class Persona {
public:
string nombre;
Persona(string n) {
nombre = n;
}
};Destructor
Limpia el objeto cuando deja de ser necesario.
~Persona() {
cout << "Objeto destruido" << endl;
}Herencia simple
Una clase puede heredar atributos y métodos de otra.
class Estudiante : public Persona {
public:
int matricula;
};Polimorfismo con clases
Permite usar una misma interfaz para distintos tipos de objetos.
class Animal {
public:
virtual void hacerSonido() const { std::cout << "Sonido de animal" << std::endl; }
};
class Perro : public Animal {
public:
void hacerSonido() const override { std::cout << "Guau!" << std::endl; }
};Excepciones
Bloques try-catch
Manejan excepciones
try {
throw std::runtime_error("Error");
} catch (const std::exception &e) {
std::cout << "Excepción capturada: " << e.what() << std::endl;
}Lanzar excepciones
Puedes lanzar excepciones en C++ usando throw.
void divide(int a, int b) {
if (b == 0) {
throw std::invalid_argument("División por cero");
}
std::cout << a / b << std::endl;
}Librerías Estándar
iostream
Proporciona funciones para entrada y salida.
#include <iostream>
using namespace std;
cout << "Hola" << endl;
cin >> variable;vector
Una estructura de datos dinámica que puede cambiar de tamaño.
#include <vector>
vector<int> v = {1, 2, 3};
v.push_back(4);
cout << v[0]; // Imprime 1algorithm
Ofrece funciones de algoritmos como búsqueda y ordenación.
#include <algorithm>
vector<int> v = {4, 1, 3, 2};
sort(v.begin(), v.end()); // Ordena el vectorMacros y Plantillas
Macros
Definen funciones o valores constantes preprocesadas.
#define PI 3.14159
#define cuadrado(x) ((x) * (x))Función plantilla
Permite definir funciones genéricas que operan con cualquier tipo de datos.
template <typename T>
T sumar(T a, T b) {
return a + b;
}Clase plantilla
Define clases genéricas.
template <class T>
class Caja {
public:
T valor;
Caja(T v) : valor(v) {}
};Conceptos
Son restricciones que permiten definir interfaces claras para plantillas.
template <typename T>
concept Numerico = std::is_arithmetic_v<T>;
template <Numerico T>
T multiplicar(T a, T b) {
return a * b;
}Archivos
Lectura y escritura de archivos
Se utilizan ifstream para lectura y ofstream para escritura.
#include <fstream>
ofstream archivo("salida.txt");
archivo << "Hola Archivo" << endl;
archivo.close();
ifstream entrada("entrada.txt");
string linea;
while (getline(entrada, linea)) {
cout << linea << endl;
}
entrada.close();Concurrencia
Threads
Manejo de hilos con std::thread
#include <thread>
void funcion() {
std::cout << "Hilo en ejecución" << std::endl;
}
int main() {
std::thread hilo(funcion); // Crear un nuevo hilo
hilo.join(); // Esperar a que el hilo termine
}Mutex y condiciones
Sincronización con mutex
#include <mutex>
std::mutex mtx;
void imprimir(int i) {
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Valor: " << i << std::endl;
}Corutinas
Permiten suspender y reanudar funciones.
#include <coroutine>
std::future<void> ejemplo() {
co_await std::chrono::seconds(1);
std::cout << "Hecho!" << std::endl;
}Gestión de Errores y Depuración
assert para depuración
Verifica condiciones en tiempo de ejecución.
#include <cassert>
int x = 5;
assert(x == 5); // Pasa, no ocurre nadacerr para errores
Muestra mensajes de error en la salida estándar de errores
cerr << "Error: Variable inválida" << endl;