Manual Completo de Programación en C++

Introducción a C++

C++ es un lenguaje de programación multiparadigma que soporta programación estructurada, orientada a objetos y genérica.

Historia y características

Primer programa

#include <iostream>

int main() {
    std::cout << "¡Hola, mundo!" << std::endl;
    return 0;
}

Fundamentos de C++

Tipos de datos básicos

int entero = 42;
float flotante = 3.14f;
double doble = 3.141592;
char caracter = 'A';
bool booleano = true;

Estructuras de control

// Condicional if-else
if (edad >= 18) {
    std::cout << "Mayor de edad" << std::endl;
} else {
    std::cout << "Menor de edad" << std::endl;
}

// Bucle for
for (int i = 0; i < 10; i++) {
    std::cout << i << " ";
}

// Bucle while
int j = 0;
while (j < 5) {
    std::cout << j << " ";
    j++;
}

Funciones

// Declaración
int suma(int a, int b);

// Definición
int suma(int a, int b) {
    return a + b;
}

// Uso
int resultado = suma(5, 3);

Programación Orientada a Objetos

Clases y objetos

class Persona {
private:
    std::string nombre;
    int edad;
    
public:
    // Constructor
    Persona(std::string nombre, int edad) : nombre(nombre), edad(edad) {}
    
    // Método
    void saludar() {
        std::cout << "Hola, soy " << nombre << std::endl;
    }
    
    // Getters y setters
    void setEdad(int nuevaEdad) { edad = nuevaEdad; }
    int getEdad() const { return edad; }
};

// Uso
Persona juan("Juan", 25);
juan.saludar();

Herencia

class Empleado : public Persona {
private:
    std::string puesto;
    
public:
    Empleado(std::string nombre, int edad, std::string puesto) 
        : Persona(nombre, edad), puesto(puesto) {}
    
    void trabajar() {
        std::cout << nombre << " está trabajando como " << puesto << std::endl;
    }
};

Polimorfismo

class Figura {
public:
    virtual double area() const = 0; // Método virtual puro
};

class Circulo : public Figura {
    double radio;
public:
    Circulo(double r) : radio(r) {}
    double area() const override { return 3.1416 * radio * radio; }
};

class Rectangulo : public Figura {
    double ancho, alto;
public:
    Rectangulo(double a, double h) : ancho(a), alto(h) {}
    double area() const override { return ancho * alto; }
};

// Uso polimórfico
void imprimirArea(const Figura& f) {
    std::cout << "Área: " << f.area() << std::endl;
}

Standard Template Library (STL)

Contenedores

#include <vector>
#include <list>
#include <map>
#include <unordered_map>
#include <set>

// Vector (array dinámico)
std::vector<int> numeros = {1, 2, 3};
numeros.push_back(4); // Añadir elemento

// Lista enlazada
std::list<std::string> nombres = {"Ana", "Juan"};
nombres.push_front("Pedro");

// Map (diccionario ordenado)
std::map<std::string, int> edades;
edades["Ana"] = 25;
edades["Juan"] = 30;

// Unordered_map (diccionario hash)
std::unordered_map<std::string, int> edades_rapido;

// Set (conjunto ordenado)
std::set<int> conjunto = {3, 1, 4, 1, 5}; // {1, 3, 4, 5}

Algoritmos

#include <algorithm>

std::vector<int> v = {5, 3, 1, 4, 2};

// Ordenar
std::sort(v.begin(), v.end());

// Buscar
auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {
    std::cout << "Encontrado: " << *it << std::endl;
}

// Contar
int unos = std::count(v.begin(), v.end(), 1);

// Transformar
std::transform(v.begin(), v.end(), v.begin(), 
    [](int n) { return n * 2; });

Iteradores

// Recorrer con iteradores
for (auto it = v.begin(); it != v.end(); ++it) {
    std::cout << *it << " ";
}

// Range-based for loop (C++11)
for (int num : v) {
    std::cout << num << " ";
}

C++ Moderno (C++11/14/17/20)

Auto y decltype

auto x = 5; // int
auto y = 3.14; // double
auto z = "Hola"; // const char*

std::vector<std::string> palabras = {"uno", "dos"};
for (auto& palabra : palabras) { // referencia para evitar copias
    palabra += "!";
}

decltype(x) w = 10; // mismo tipo que x (int)

Lambdas

auto suma = [](int a, int b) { return a + b; };
std::cout << suma(3, 4) << std::endl; // 7

std::vector<int> nums = {1, 2, 3, 4};
int total = 0;
std::for_each(nums.begin(), nums.end(), [&total](int n) {
    total += n;
});

Smart pointers

#include <memory>

// Unique_ptr (propiedad única)
std::unique_ptr<int> ptr1 = std::make_unique<int>(42);

// Shared_ptr (conteo de referencias)
std::shared_ptr<int> ptr2 = std::make_shared<int>(10);
auto ptr3 = ptr2; // ahora hay 2 referencias

// Weak_ptr (referencia sin propiedad)
std::weak_ptr<int> ptr4 = ptr2;

Multithreading

#include <thread>
#include <mutex>
#include <future>

std::mutex mtx;

void funcion_hilo(int id) {
    std::lock_guard<std::mutex> lock(mtx);
    std::cout << "Hilo " << id << " ejecutándose" << std::endl;
}

int main() {
    std::thread t1(funcion_hilo, 1);
    std::thread t2(funcion_hilo, 2);
    
    t1.join();
    t2.join();
    
    // Futuros y promesas
    std::promise<int> prom;
    std::future<int> fut = prom.get_future();
    
    std::thread t3([](std::promise<int>& p) {
        p.set_value(42);
    }, std::ref(prom));
    
    std::cout << "Resultado: " << fut.get() << std::endl;
    t3.join();
    
    return 0;
}

SDL (Simple DirectMedia Layer)

#include <SDL2/SDL.h>

int main(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_VIDEO);
    
    SDL_Window* window = SDL_CreateWindow(
        "SDL Demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        800, 600, SDL_WINDOW_SHOWN);
    
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 
        SDL_RENDERER_ACCELERATED);
    
    bool running = true;
    SDL_Event event;
    
    while (running) {
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                running = false;
            }
        }
        
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        
        // Dibujar un rectángulo rojo
        SDL_Rect rect = {100, 100, 200, 150};
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        SDL_RenderFillRect(renderer, &rect);
        
        SDL_RenderPresent(renderer);
    }
    
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    
    return 0;
}

Biblioteca Boost

Boost.Asio (Networking)

#include <boost/asio.hpp>
#include <iostream>

using boost::asio::ip::tcp;

int main() {
    try {
        boost::asio::io_context io_context;
        
        // Crear socket
        tcp::socket socket(io_context);
        
        // Conectar
        tcp::resolver resolver(io_context);
        boost::asio::connect(socket, resolver.resolve("example.com", "80"));
        
        // Enviar solicitud HTTP
        std::string request = "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n";
        boost::asio::write(socket, boost::asio::buffer(request));
        
        // Leer respuesta
        boost::asio::streambuf response;
        boost::asio::read_until(socket, response, "\r\n");
        
        // Mostrar respuesta
        std::istream response_stream(&response);
        std::string http_version;
        unsigned int status_code;
        response_stream >> http_version >> status_code;
        
        std::cout << "Respuesta: " << status_code << std::endl;
    } catch (std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
    
    return 0;
}

Boost.Filesystem

#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;

int main() {
    // Crear directorio
    fs::path dir("mi_directorio");
    if (!fs::exists(dir)) {
        fs::create_directory(dir);
    }
    
    // Listar archivos
    for (const auto& entry : fs::directory_iterator(".")) {
        std::cout << entry.path() << std::endl;
    }
    
    // Copiar archivo
    fs::copy_file("origen.txt", "destino.txt");
    
    return 0;
}

OpenGL

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>

const char* vertexShaderSource = R"(
    #version 330 core
    layout (location = 0) in vec3 aPos;
    void main() {
        gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
    }
)";

const char* fragmentShaderSource = R"(
    #version 330 core
    out vec4 FragColor;
    void main() {
        FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
    }
)";

int main() {
    glfwInit();
    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Demo", NULL, NULL);
    glfwMakeContextCurrent(window);
    glewInit();
    
    // Compilar shaders
    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    
    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    
    // Crear programa
    unsigned int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    
    // Datos del triángulo
    float vertices[] = {
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f,  0.5f, 0.0f
    };
    
    // Configurar VBO y VAO
    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    
    // Bucle principal
    while (!glfwWindowShouldClose(window)) {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(shaderProgram);
    
    glfwTerminate();
    return 0;
}

OpenCV

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // Leer imagen
    cv::Mat image = cv::imread("imagen.jpg");
    if (image.empty()) {
        std::cerr << "No se pudo cargar la imagen" << std::endl;
        return -1;
    }
    
    // Mostrar imagen original
    cv::imshow("Imagen Original", image);
    
    // Convertir a escala de grises
    cv::Mat gray;
    cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
    
    // Detectar bordes
    cv::Mat edges;
    cv::Canny(gray, edges, 50, 150);
    
    // Detectar caras (usando Haar Cascade)
    cv::CascadeClassifier face_cascade;
    if (!face_cascade.load("haarcascade_frontalface_default.xml")) {
        std::cerr << "No se pudo cargar el clasificador" << std::endl;
        return -1;
    }
    
    std::vector<cv::Rect> faces;
    face_cascade.detectMultiScale(gray, faces);
    
    // Dibujar rectángulos alrededor de las caras
    for (const auto& face : faces) {
        cv::rectangle(image, face, cv::Scalar(0, 255, 0), 2);
    }
    
    // Mostrar resultados
    cv::imshow("Bordes", edges);
    cv::imshow("Detección de caras", image);
    
    // Guardar imagen procesada
    cv::imwrite("resultado.jpg", image);
    
    cv::waitKey(0);
    return 0;
}

Buenas Prácticas y Consejos

Manejo de memoria

Seguridad y robustez

Optimización

Recursos Adicionales

Documentación oficial

Libros recomendados